Avaleht
uus teema   vasta Tarkvara »  Programmeerimine »  PHP5 OOP küsimused märgi kõik teemad loetuks
märgi mitteloetuks
vaata eelmist teemat :: vaata järgmist teemat
mine lehele 1, 2, 3, 4  järgmine
Hinnavaatlus :: Foorum :: Uudised :: Ärifoorumid :: HV F1 ennustusvõistlus :: Pangalink :: Telekavad :: HV toote otsing
autor
sõnum Saada viide sõbrale. Teata moderaatorile
otsing:  
keevitaja
AM 10 aastat
keevitaja

liitunud: 05.11.2001




sõnum 30.12.2008 17:32:27 PHP5 OOP küsimused vasta tsitaadiga

<?php
class kala
{
   function get($string)
   {
      $this->string = $string;
   }
   
   public function add()
   {
      $this->string .= ' !!!';
   }
}

class mala Extends kala
{
   function show()
   {
      $this->add();
      
      print $this->string;
   }
}

$obj = new mala;

$obj->get('See on proov');
$obj->show();
?>


mida täpselt teeb see Extends? Põhimõtteliselt paneb esimise classi teise sisse? ja mis vahet on public function ja tavalise vahet?
Kommentaarid: 51 loe/lisa Kasutajad arvavad:  :: 1 :: 3 :: 40
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
ref
Kreisi kasutaja

liitunud: 10.08.2003




sõnum 30.12.2008 17:40:29 vasta tsitaadiga

Põhimõtteliselt on see tavaline objektorienteeritud pärimine ja nähtavus icon_wink.gif
Extends - laiendab baasklassi (ehk siis sinu näites: klass mala pärineb klassist kala).
public - selle võtmega funktsioon on väljaspoolt nähtav ja väljakutsutav (by default OO lähenemise juures saad sa vaid public funktsioone/muutujaid välja kutsuda)
(ok, ma ise pole väga php progeja ja eelpoolne oli OO üldiselt, PHP on veidi imelik oma objektide osas).

AGA kindlasti on abiks manuaali lugemine ja OO põhitõdede selgeks tegemine:
http://ee2.php.net/zend-engine-2.php ja http://en.wikipedia.org/wiki/Object-oriented_programming
Kommentaarid: 17 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 15
tagasi üles
vaata kasutaja infot saada privaatsõnum
keevitaja
AM 10 aastat
keevitaja

liitunud: 05.11.2001




sõnum 30.12.2008 17:46:58 vasta tsitaadiga

aga ma ei saa ikkagi aru, mis mõttes seda public functionit saab väljaspoolt kutsuda?
_________________
Hinnavaatlus ei ole koht arvamuse avaldamiseks!
Kommentaarid: 51 loe/lisa Kasutajad arvavad:  :: 1 :: 3 :: 40
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
keevitaja
AM 10 aastat
keevitaja

liitunud: 05.11.2001




sõnum 30.12.2008 18:02:58 vasta tsitaadiga

<?php
class kala
{
   function get($string)
   {
      $this->string = $string;
   }
   
   public function add()
   {
      $this->string .= ' !!!';
   }
}

class mala Extends kala
{
   function show()
   {
      $this->add();
      
      print $this->string;
   }
}

class jama Extends kala
{
   function show()
   {
      print '<hr>'.$this->string.' mida hekki';
   }
}

$obj = new mala;
$new = new jama;

$obj->get('See on proov');
$obj->show();
$new->get('See on proov');
$new->show();
?>


kas ilma selle extendita ma peaks constructima kala viimases kahes classis et teda seal kasutada?
Kommentaarid: 51 loe/lisa Kasutajad arvavad:  :: 1 :: 3 :: 40
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
ref
Kreisi kasutaja

liitunud: 10.08.2003




sõnum 30.12.2008 18:20:56 vasta tsitaadiga

keevitaja kirjutas:
aga ma ei saa ikkagi aru, mis mõttes seda public functionit saab väljaspoolt kutsuda?

Okei seletame OO-d siis veidi (see ei ole PHP spetsiifiline, see on üleüldine OO, kood ei ole PHP!)

Privaatseid muutujaid/funktsioone ei saa sa selle objekti käest küsida (st. teed objekti ja püüad midagi privaatset küsida saad pasunasse, kuna see on keelatud), privaatset asja saad kasutada ainult objekti enda siseselt (a'la jagad mingi keerulisema funktsiooni juppideks aga sa ei taha, et neid juppe omakorda objekti käest küsida).

Avalikud muutujad/funktsioonid on selleks, et sa saaksid objekti käest mingeid asju küsida/muuta/lisada (ehk siis kogu suhtlemine objekti endaga).

ehk siis piltlikult: sul on klass kala, millel on public (avalik) funktsioon foo ja privaatne funktsioon bar; sa tekitad uue objekti muutujasse asd ($asd = new kala()) ja püüdes käivitada klassi kala küljes olevat funktsiooni bar ($asd->bar()) saad sa pasunasse (funktsiooni ei eksisteeri vms on veateateks), käivitades funktsiooni foo ($asd->foo()) toimib kõik ilusasti.

veel veidi üleüldisi näiteid:
sul on klass ja funktsioonid/meetodid:

class minuklass
{
  private int muutuja;

  //constructor, st. see on meetod/funktsioon mis loob meile vajaliku objekti/klassi
  public minuklass()
  {
    //siin tehakse mingit maagiat mis vaja, näiteks algväärtustame privaatse muutuja
   muutuja = 10;
  }

  private int privaatnefunktsioon()
  {
    return muutuja * 2;
  }

  public int avalikfunktsioon(int kohalikmuutuja)
  {
    muutuja = kohalikmuutuja; //väärtustame klassisisese privaatse muutuja
    return privaatnefunktsioon;
  }
}


Nüüd pisike kasutamise näide:

klass = new minuklass(); //tekitame uue objekti/klassi mis meil eespool kirjeldatud on

//kutsume välja klassis olevaid meetodeid ja selgitame kas ja miks asi töötab/ei tööta nii

//1. püüame väärtustada privaatset muutujat:
klass.muutuja = 10; //selle peale peaks tulema vastus, et muutuja on unknown või not accessible in this contex (sõltuvalt keelest ja keskkonnast)

//2. kustume välja avaliku funktsiooni
klass.avalikfunktsioon(20); //tagastab 40, vt. eestpoolt

//3. kutsume välja privaatse funktsiooni
klass.privaatnefunktsioon; //sama reaktsioon mis privaatse muutuja väärtustamisel


e:

keevitaja kirjutas:

kas ilma selle extendita ma peaks constructima kala viimases kahes classis et teda seal kasutada?

You got it, partially..

Soovitus soojalt: loe OO progemise põhitõdesid alustuseks, kui need mingil määral hakkavad selgeks saama võta kõrvale konkreetne keel (kasvõi PHP) ja hakka katsetama, nii saad kõige paremini selgeks (st. katseta erinevaid kombinatsioone ja nii saad vast kõige paremini aru kuidas nähtavused ja pärimised toimivad).

Ps. PHP ei ole tegelikult OO jaoks hea keel õppimiseks (java, ruby vms OO keel oleks parem aga PHP ajab ka vajadusel asja ära!)
Kommentaarid: 17 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 15
tagasi üles
vaata kasutaja infot saada privaatsõnum
keevitaja
AM 10 aastat
keevitaja

liitunud: 05.11.2001




sõnum 06.01.2009 15:42:05 vasta tsitaadiga

<?php
class klass
{
   public $kala = $_SERVER['REMOTE_ADDR'];
   
   public function fun()
   {
      echo $this->kala;
   }
}

$obj = new klass;
$obj->fun();
?>


public $kala annab errori selle $_SERVER väärtuse peale. kas sellest kuidagi mööda saab minna või ei saa niimoodi üldse?
Kommentaarid: 51 loe/lisa Kasutajad arvavad:  :: 1 :: 3 :: 40
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
troglodyte
Kreisi kasutaja
troglodyte

liitunud: 09.08.2002




sõnum 06.01.2009 16:47:11 vasta tsitaadiga

Klassi muutujaid deklareerides saab neile ainult konstante omistada (mitte teiste muutujate väärtusi jms): Vt. Example #3
Küll aga saaksid sa seda konstruktoris.
php:
  1. class klass {
  2.    public $kala;
  3.    public function __construct() {
  4.      $this->kala = $_SERVER['REMOTE_ADDR'];
  5.    }
  6.    // ...
  7. }

_________________
ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn
Kommentaarid: 33 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 33
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
keevitaja
AM 10 aastat
keevitaja

liitunud: 05.11.2001




sõnum 06.01.2009 17:49:58 vasta tsitaadiga

aga kas seda on mõttekas niimoodi kasutada? ehk lihtsalt kasutakski $_SERVER['REMOTE_ADDR']
_________________
Hinnavaatlus ei ole koht arvamuse avaldamiseks!
Kommentaarid: 51 loe/lisa Kasutajad arvavad:  :: 1 :: 3 :: 40
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
Renka
HV Guru
Renka

liitunud: 01.04.2002



Autoriseeritud ID-kaardiga

sõnum 06.01.2009 17:58:03 vasta tsitaadiga

mõttekas on näiteks nii kasutada.
Sellepärast, et vahest brausitakse proxy tagant vmt siis saab õige IP aadressi kätte nii.

Mujal koodi saad siis seda ühte konkreetset mutujat kasutada mitte ei pea iga kord samasugust if lauset kirjutama.
php:
  1. class klass {
  2.    public $kala;
  3.    public function __construct() {
  4.      if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
  5.        $this->kala = $_SERVER['HTTP_X_FORWARDED_FOR'];
  6.      } else {
  7.        $this->kala = $_SERVER['REMOTE_ADDR'];
  8.      }
  9.    }
  10.    // ...
  11. }

_________________
There is no place like 127.0.0.1
Kommentaarid: 71 loe/lisa Kasutajad arvavad:  :: 2 :: 1 :: 61
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
keevitaja
AM 10 aastat
keevitaja

liitunud: 05.11.2001




sõnum 06.01.2009 19:05:05 vasta tsitaadiga

aga kas see __construct on põmst selline asi, mis käivitatakse ilma väljakutsumata koheselt objekti tekitamisel?
_________________
Hinnavaatlus ei ole koht arvamuse avaldamiseks!
Kommentaarid: 51 loe/lisa Kasutajad arvavad:  :: 1 :: 3 :: 40
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
ref
Kreisi kasutaja

liitunud: 10.08.2003




sõnum 06.01.2009 19:22:14 vasta tsitaadiga

keevitaja kirjutas:
aga kas see __construct on põmst selline asi, mis käivitatakse ilma väljakutsumata koheselt objekti tekitamisel?

jah
Kommentaarid: 17 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 15
tagasi üles
vaata kasutaja infot saada privaatsõnum
mikk36
HV Guru
mikk36

liitunud: 21.02.2004




sõnum 06.01.2009 19:32:28 vasta tsitaadiga

Renka kirjutas:
mõttekas on näiteks nii kasutada.
Sellepärast, et vahest brausitakse proxy tagant vmt siis saab õige IP aadressi kätte nii.

Mujal koodi saad siis seda ühte konkreetset mutujat kasutada mitte ei pea iga kord samasugust if lauset kirjutama.
php:
  1. class klass {
  2.    public $kala;
  3.    public function __construct() {
  4.      if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
  5.        $this->kala = $_SERVER['HTTP_X_FORWARDED_FOR'];
  6.      } else {
  7.        $this->kala = $_SERVER['REMOTE_ADDR'];
  8.      }
  9.    }
  10.    // ...
  11. }
Teatud puhkudel saab sellega teada kliendi sisevõrgu ip (juhul kui liiklus internetti on suunatud läbi sisevõrgus asuva proxy).
Kommentaarid: 85 loe/lisa Kasutajad arvavad:  :: 0 :: 2 :: 78
tagasi üles
vaata kasutaja infot saada privaatsõnum
keevitaja
AM 10 aastat
keevitaja

liitunud: 05.11.2001




sõnum 07.01.2009 13:17:32 vasta tsitaadiga

link :: audentimissüsteem

nikerdasin nüüd mingi kasutaja autentimise süsteemi valmis. kas keegi viitsiks kommenteerida seda OOPi (kui see üldse on OOP mida ma kirjutasin) ja samas ka kas süsteem on turvaline. mis on valesti tehtud jne

installimiseks tuleb panna conf.php failis mysql andmed paika ja siis käivitada install.php

conf.php
php:
  1.  
  2. <?php
  3. $SQL_DB = 'test';
  4. $SQL_HOST = 'localhost';
  5. $SQL_USER = 'root';
  6. $SQL_PASS = 'kala';
  7.  
  8. define(S_TIME, 300);
  9. define(DB_PER, 'dalhf_');
  10. define(COOKIE_NAME, 'dsfsdjfl4j');
  11.  
  12. mysql_select_db($SQL_DB, mysql_connect($SQL_HOST, $SQL_USER, $SQL_PASS)) or die(mysql_error());
  13.  
  14. define(DB_USER, DB_PER.'user');
  15. define(DB_GSESS, DB_PER.'gsess');
  16. define(DB_USESS, DB_PER.'usess');
  17. ?>
  18.  


install.php
php:
  1.  
  2. <?php
  3. require('./conf.php');
  4. require('mysql.class.php');
  5.  
  6. $db = new MysqlDB;
  7.  
  8. $cmd[DB_USER] = "
  9.         user_id int primary key not null auto_increment,
  10.         user_name varchar(20),
  11.         user_pass varchar(32),
  12.         user_realname varchar(32),
  13.         user_email varchar(32)
  14.         ";
  15.        
  16. $cmd[DB_GSESS] = "
  17.         sess_id int primary key not null auto_increment,
  18.         hash varchar(32),
  19.         ip varchar(15)
  20.         ";
  21.        
  22. $cmd[DB_USESS] = "
  23.         sess_id int,
  24.         time int,
  25.         user_id int
  26.         ";
  27.  
  28. foreach($cmd as $tbl => $sql_cmd)
  29. {
  30.         if(!$db->num_rows($db->query("SHOW TABLES LIKE '".$tbl."'")))
  31.         {
  32.                 $mysql_cmd = "create table ".$tbl."(".$sql_cmd.")";
  33.                 $db->query($mysql_cmd);
  34.         }
  35. }
  36.  
  37. $db->query("insert into ".DB_USER."(user_name, user_pass) values('admin', '".md5('admin')."')");
  38. ?>
  39.  



kala.php
php:
  1.  
  2. <?php
  3. require('conf.php');
  4. require('mysql.class.php');
  5. require('session.php');
  6.  
  7. echo '<a href="' . $sess->url('kala.php') . '">refresh</a><hr>';
  8.  
  9. if($sess->auth_user())
  10.         echo '<b>Kasutaja on sisse logitud!</b> <a href="'.$sess->url('login.php').'">Logout</a>';
  11. else
  12.         echo 'Kasutaja ei ole sisse logitud! <a href="'.$sess->url('login.php').'">Login</a>';
  13. ?>
  14.  


login.php
php:
  1.  
  2. <?php
  3. require('conf.php');
  4. require('mysql.class.php');
  5. require('session.php');
  6.  
  7. if(!$sess->auth_user())
  8. {
  9.         if($_POST['user_name'] && $_POST['user_pass'])
  10.         {
  11.                 if($sess->user_check($_POST['user_name'], $_POST['user_pass']))
  12.                 {
  13.                         $sess->login();
  14.                        
  15.                         header('Location: '.$sess->url('kala.php'));
  16.                 }
  17.                 else
  18.                         echo 'Kasutajat ei ole olemas! <a href="'.$sess->url('login.php').'">Uuesti logima >>></a>';
  19.         }
  20.         else
  21.         {
  22. ?>
  23. <form action="login.php" method="post">
  24. <?php
  25.                 if(!$sess->auth_method)
  26.                 {
  27. ?>
  28.         <input type="hidden" name="sid" value="<?php echo $sess->sid ?>">
  29. <?php
  30.                 }
  31. ?>
  32.         <p>kasutaja <input type="text" name="user_name"></p>
  33.         <p>parool <input type="password" name="user_pass"></p>
  34.         <p><input type="submit" value="Login"></p>
  35. </form>
  36. <?php
  37.         }
  38. }
  39. else
  40. {
  41.         $sess->logout($sess->user_id);
  42.         echo 'Kasutaja on v2lja logitud! <a href="'.$sess->url('login.php').'">Uuesti logima >>></a>';
  43. }
  44. ?>
  45.  



mysql.class.php
php:
  1.  
  2. <?php
  3. class MysqlDB
  4. {
  5.         public function error()
  6.         {
  7.                 return die(mysql_error().' ('.mysql_errno().')');
  8.         }
  9.  
  10.         public function query($query)
  11.         {
  12.                 return mysql_query($query);
  13.         }
  14.        
  15.         public function fetch_assoc($result)
  16.         {
  17.                 return mysql_fetch_assoc($result);
  18.         }
  19.        
  20.         public function num_rows($result)
  21.         {
  22.                 return mysql_num_rows($result);
  23.         }
  24.        
  25.         public function result($query)
  26.         {
  27.                 $sql_query = $this->query($query);
  28.                 return $this->fetch_assoc($sql_query);
  29.         }
  30.        
  31.         public function insert_id()
  32.         {
  33.                 return mysql_insert_id();
  34.         }
  35. }
  36. ?>
  37.  



session.class.php
php:
  1.  
  2. <?php
  3. class session Extends MysqlDB
  4. {
  5.         public $remote_ip;
  6.  
  7.         public function __construct()
  8.         {
  9.                 if (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
  10.                 {
  11.                         $this->remote_ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
  12.                 }
  13.                 else
  14.                 {
  15.                         $this->remote_ip = $_SERVER['REMOTE_ADDR'];
  16.                 }
  17.         }
  18.        
  19.         public function start()
  20.         {
  21.                 //kontrollime, kas kypsised on lubatud
  22.                 $this->auth_method = (array_key_exists(COOKIE_NAME, $_COOKIE)) ? true : false;
  23.                
  24.                 //session id
  25.                 $this->sid = (strlen($_REQUEST['sid']) == 32) ? $_REQUEST['sid'] : $_COOKIE[COOKIE_NAME];
  26.         }
  27.        
  28.         public function validate()
  29.         {
  30.                 //kontrollime, kas sessioon on kehtiv
  31.                 $session = $this->result("select count(sess_id) as c from ".DB_GSESS." where
  32.                         hash='$this->sid' and ip='$this->remote_ip'") or die($this->error());
  33.                        
  34.                 if($session['c'] != 0)
  35.                 {
  36.                         $sess_id = $this->result("select sess_id from ".DB_GSESS." where
  37.                                 hash='$this->sid' and ip='$this->remote_ip'") or die($this->error());
  38.                                
  39.                         $this->sess_id = $sess_id['sess_id'];
  40.                                
  41.                         return true;
  42.                 }
  43.                        
  44.                
  45.         }
  46.        
  47.         public function new_gsess()
  48.         {
  49.                 //kui pole sellist sessio olemas, siis sisestame uue
  50.                 $this->sid = md5(time() + microtime());
  51.                
  52.                 setcookie(COOKIE_NAME, $this->sid);
  53.                
  54.                 $this->query("insert into ".DB_GSESS."(hash, ip)
  55.                         values('$this->sid', '$this->remote_ip')") or die($this->error());
  56.         }
  57.        
  58.         //kui cookied pole lubatud, siis lisama PHPSESSID urlile
  59.         public function url($url)
  60.         {
  61.                 if(!$this->auth_method)
  62.                         return $url . ((strstr($url, '?')) ? '&' : '?') . 'sid=' . $this->sid;
  63.                 else
  64.                         return $url;
  65.         }
  66.        
  67.         //kontrollime, kas kylastaja on sisse logitud
  68.         public function auth_user()
  69.         {
  70.                 $time = time() - S_TIME;
  71.                
  72.                 $auth = $this->result("select user_id from ".DB_USESS." where
  73.                         sess_id='$this->sess_id' and time>='$time'");
  74.                        
  75.                 if(is_numeric($auth['user_id']))
  76.                 {
  77.                         $this->user_id = $auth['user_id'];
  78.                         $time = time();
  79.                        
  80.                         $this->query("update ".DB_USESS." set time='$time' where
  81.                                 sess_id='$this->sess_id' and time>='$time'");
  82.                                
  83.                         return true;
  84.                 }
  85.         }
  86.        
  87.         //logime kasutaja sisse
  88.         public function user_check($user_name, $user_pass)
  89.         {
  90.                 $user_name = trim($_POST['user_name']);
  91.                 $user_pass = md5($_POST['user_pass']);
  92.                
  93.                 $auth = $this->result("select user_id from ".DB_USER." where
  94.                         user_name='$user_name' and user_pass='$user_pass'");
  95.                        
  96.                 $this->user_id = $auth['user_id'];     
  97.                        
  98.                 if(is_numeric($this->user_id))
  99.                         return true;
  100.         }
  101.        
  102.         public function login()
  103.         {
  104.                 $time = time();
  105.                
  106.                 $this->query("insert into ".DB_USESS."(sess_id, time, user_id) values(
  107.                         '$this->sess_id', '$time', '$this->user_id')") or die($this->error());
  108.         }
  109.        
  110.         public function logout($user_id)
  111.         {
  112.                 $this->query("delete from ".DB_USESS." where user_id='$user_id'");
  113.                 setcookie(COOKIE_NAME, '', time()-3600);
  114.                 $this->sid = md5(time() + microtime());
  115.         }
  116.        
  117. }
  118.  



session.php
php:
  1.  
  2. <?php
  3. require('session.class.php');
  4.  
  5. //alustame uue sessiooni majandusega
  6. $sess = new session;
  7. $sess->start();
  8.  
  9. if(!$sess->validate())
  10.         $sess->new_gsess();
  11.  
  12. ?>
  13.  
Kommentaarid: 51 loe/lisa Kasutajad arvavad:  :: 1 :: 3 :: 40
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
inzinz
HV kasutaja

liitunud: 26.01.2005




sõnum 07.01.2009 14:03:58 vasta tsitaadiga

SQL injectioni probleemid on sees, proovi näiteks sisse logida nii et paned kasutajanime lahtrisse eksisteeriv kasutajanimi ja selle järgi kohe '#
Näiteks
kasutaja: admin'#
parool:suvakas
Kui php's on magic_quotes_gpc peal, siis ei juhtu midagi (õnneks), aga kui ei ole peal, siis saad ilma õiget parooli teadmata sisse logida icon_biggrin.gif

Soovitan teha mingi üldise funktsiooni make_safe() mis oleks põhimõtteliselt midagi taolist

function make_mysql_safe($orig) {
return mysql_real_escape_string(get_magic_quotes_gpc() ? stripslashes($orig) : $orig );
}

Eemaldab üleliigsed slashid ära stringist kui vaja ning muudab stringi mysql'le ette söötmiseks sobivaks (escapeb kindlad vajalikud characterid ära).

Kasutaksid siis oma user_check funktsioonis umbes nii

$user_name = make_mysql_safe(trim($_POST['user_name']));


Üldiselt tuleb üritada lähtuda reeglist et kõik mysql'le ette söödetav info peab läbi käima mysql_real_escape_string funktsiooni kuna muidu on kiirelt jamad tulema nagu ma ülevalpool kirjeldasin sisselogimisega. Nüüd kujuta ette kui sul on update päring ja pahatahtlikul kasutajal on ülevaade tabeli struktuurist, siis piisab kui ta paneb kuskile välja sisse väärtuse: pla',väli1='',väli2='',väli3='',väli4=''#
mispeale tühjendatakse kogu sinu users tabel andmetest (või mõni muu tabel mille update oleks see leht pidanud tegema).

Lisaks küsimus, mis sul user_check funktsioon aktsepteerib username ja password väärtusi, kui ise hoopis $_POST massiivi kallale läheb ikkagi ?

Kui need sql injectioni vead välja saad igalt poolt, siis on kood juba vägagi asjalik: täidab oma ülesannet ja on veakindel

_________________
Upload.ee - eestimaine failiupload
Kommentaarid: 4 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 4
tagasi üles
vaata kasutaja infot saada privaatsõnum
keevitaja
AM 10 aastat
keevitaja

liitunud: 05.11.2001




sõnum 07.01.2009 15:01:08 vasta tsitaadiga

kas seda make_safe() peaks iga mysql päringu kallal kasutama? kaasaarvatud paroolil ja üle urli võetavast sessiooni hashil?

user_check oli mõttetu jah icon_lol.gif
Kommentaarid: 51 loe/lisa Kasutajad arvavad:  :: 1 :: 3 :: 40
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
inzinz
HV kasutaja

liitunud: 26.01.2005




sõnum 07.01.2009 15:22:54 vasta tsitaadiga

Parool on eraldi case natuke, seal peale md5 tegemist ei ole sees midagi imelikku mis võiks päringu ära rikkuda, vaid ainult 32 tähemärki vahemikus 1-f.
Mul on muidu keerukamad funktsioonid ka tehtud mis võimaldavad get ja post parameetreid turvaliselt sisse lugeda: http://board.koffer.ee/viewtopic.php?p=1933696#1933696
Nood funktsioonid seal peaks vist defaultina HTML safe'ks ka tegema, et sa ei pea isegi selle pärast muretsema kui keegi sulle html koodi sisse söödab formis, sinu kood teeb ikkagi tuvaliseks ja ei kuva kuskile reaalset html koodi.

Aga üldiselt jah, soovitan sul teha omale mingid funktsioonid mis päringu parameetrid turvaliseks teeks: just html mõttes mis on väga tavaline viga pluss töötaks igal pool samamoodi, olenemata kas magic_quotes on sees/väljas
Lisaks siis mysql päringute juures igal pool mysql_real_escape_string kasutada.

Kui kõik õigesti teha, siis viib kogu ülalpool nimetatud tegevus/baasfunktsioonid sind ühe suure sammu võrra lähemale heaks programmeerijaks olemisele (sa ei pea enam igal pool koodis nuputama add ja stripslashesiga ja htmlspecialchars'ga vaid saad keskenduda lihtsalt progemisele). icon_smile.gif

_________________
Upload.ee - eestimaine failiupload
Kommentaarid: 4 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 4
tagasi üles
vaata kasutaja infot saada privaatsõnum
nene
Kreisi kasutaja
nene

liitunud: 20.03.2004




sõnum 07.01.2009 16:08:43 vasta tsitaadiga

Esiteks paistab, et sa leiutad jalgratast. PHP-s on ju sessioonid kenasti olemas. Miks kirjutada omaenda sessioonide haldamise süsteem?

SQL injectioni probleemid on aga peamiselt selle tagajärg, et PHP poolt pakutavad andmebaasi ühendumise vahendid on ääretult primitiivsed. Küsid täiesti õigustatult, et kas peaksid seda make_safe() iga päringu puhul kasutama - see on ju tüütu. Jah see on tüütu ning veelgi enam - see on sama koodi kordamine mitmes kohas, mis on alati halb programmeerimispraktika.

Parem kasuta mõnda andmebaasiklassi, mis lubab kasutada parameetritega päringuid. Näiteks midagi sellist:

$db->query("SELECT * FROM users WHERE name=? and pass=?", $name, $pass);


Päringus olevad küsimärgid asendab andmebaasiklass ise muutujate $name ja $pass väärtustega, mis ühtlasi varjestatakse make_safe() stiilis ning ümbritsetakse jutumärkidega. Proovi näiteks PEARi DB või MDB2 klassi. Või kirjuta enda oma, mis oskaks parameetritega päringuid käsitleda (mulle näiteks ei istu kumbki neist PEARi klassidest).

Rääkides OOPist, siis pärimist (extends) tuleks kasutada vaid klasside vahel, mille vahel valitseb on seos. Ehk siis kui class A extends B siis võiksime öelda, et A on B. Näiteks class Koer extends Loom on korrektne, sest Koer on Loom. Idee on selles, et kui meil on näiteks funktsioon paarita(loom1, loom2), mis oskab toimetada Loomadega, siis kuna Koer on samuti Loom, saame tollele funktsioonile ette anda ka kaks koera ning funktsioon tagastab meile toreda kutsika, olgugi, et tegelikult ei tea paarita() funktsioon Koertest midagi.

Sinul on class Session extends MysqlDB, aga minu meelest pole päris õige väita et Sessioon on MySQL-i andmebaas. Pigem on nii, et Sessioon kasutab MySQL-i andmebaasi. Kuid taolisel juhul pole pärimine õige viis nende klasside sidumiseks. Õige oleks, et iga Sessiooni objekt sisaldaks endas andmebaasi objekti (ehk siis tal oleks väli private mysqlDB;).

Mainin ka seda, et üldine praktika on, et klasside nimed algavad suure tähega. Ehk siis mitte session vaid Session.

Ja see ka, et kostantide S_TIME, DB_GSESS ja DB_USESS nimed on väga raskesti mõistetavad.

_________________
Mõistus otsas? Pane pinusse...
Kommentaarid: 24 loe/lisa Kasutajad arvavad:  :: 0 :: 1 :: 23
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
keevitaja
AM 10 aastat
keevitaja

liitunud: 05.11.2001




sõnum 07.01.2009 16:38:03 vasta tsitaadiga

kuidas too funktsioon välja näeks?

nene kirjutas:

$db->query("SELECT * FROM users WHERE name=? and pass=?", $name, $pass);




ja sellest ma kah aru ei saa. mida ma tegema peaksin?

nene kirjutas:

Õige oleks, et iga Sessiooni objekt sisaldaks endas andmebaasi objekti (ehk siis tal oleks väli private mysqlDB;).
Kommentaarid: 51 loe/lisa Kasutajad arvavad:  :: 1 :: 3 :: 40
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
keevitaja
AM 10 aastat
keevitaja

liitunud: 05.11.2001




sõnum 07.01.2009 16:46:00 vasta tsitaadiga

niimoodi saaks kah, aga see pole vist kah õige?
asi selles, et tahan seda mysqli klassi teiste klasside sees kasutada, ilma et peaks alati constructima. või oleks just `constructides õige?

php:
  1. <?php
  2. class Klass
  3. {       
  4.         public function upper($text)
  5.         {
  6.                 return strtoupper($text);
  7.         }
  8. }
  9.  
  10. class Teine
  11. {
  12.         function show($text)
  13.         {
  14.                 print Klass::upper($text);
  15.         }
  16. }
  17.  
  18. $obj = new Teine;
  19. $obj->show('kunagi l6ppeb k6ik');
  20.  
  21. ?>
Kommentaarid: 51 loe/lisa Kasutajad arvavad:  :: 1 :: 3 :: 40
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
inzinz
HV kasutaja

liitunud: 26.01.2005




sõnum 07.01.2009 17:26:49 vasta tsitaadiga

Siis on sul vaja uurida static funktsioonide kohta.

Põhimõtteliselt saad teha nii

class Mysql {
    public static function Init($host, $username, $password, $dbname) {
         mysql_connect($host, $username, $password);
         mysql_select_db($dbname);
    }
    public static function Query($sql) {
        return mysql_query($sql);
    }
/**
muud funktsioonid siia samas stiilis (static parameetriga)
*/
}

ja siis kasutad koodis nii, et new Mysql() asemel teed
Mysql::Init($host, $user, $pass, $dbname);

ja hiljem kasutad igal pool (nii funktsioonides kui ka klassides)
$res = Mysql::Query('select something from somewhere');

Ei pea kusagil tegema uut klassi ega ka iga funktsiooni algusesse kirjutama "global $db;"

_________________
Upload.ee - eestimaine failiupload
Kommentaarid: 4 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 4
tagasi üles
vaata kasutaja infot saada privaatsõnum
nene
Kreisi kasutaja
nene

liitunud: 20.03.2004




sõnum 07.01.2009 20:03:11 vasta tsitaadiga

keevitaja kirjutas:
kuidas too funktsioon välja näeks?


Sa mõtled, kuidas sellist funktsiooni ise kirjutada? Noh, see pole just triviaalne. Nõuab üksjagu nuputamist. Mitte midagi sellist, mida ma kohe kähku siia klaviatuurilt toksiks.

Rääkides sellest üks-klass-teise-sees-asjast, siis ma pidasin silmas midagi sellist:

php:
  1. <?php
  2. class Mootor {
  3.     public function start($text) {
  4.         echo "Nõka-nõka põrr-põrrrrr...";
  5.     }
  6.     public function stop($text) {
  7.         echo "Põrr-põrr pssss...";
  8.     }
  9. }
  10.  
  11. class Auto {
  12.     private $mootor;
  13.    
  14.     function __construct() {
  15.         $this->mootor = new Mootor;
  16.     }
  17.    
  18.     function soida($kui_kaua) {
  19.         print $this->mootor->start();
  20.         sleep($kui_kaua);
  21.         print $this->mootor->stop();
  22.     }
  23. }
  24. ?>


Selline süsteem töötab kenasti siis kui sobib, et igal Autol on oma Mootor. Teinekord on aga tarvis, et üks ja sama objekt oleks kasutusel mitmes n.ö. peremeesobjektis. Autode puhul oleks imelik, kui kõik Autod jagaksid sama Mootorit. Samas andmebaasiühenduse puhul on tavaline, et sama ühendust kasutavad korraga mitu objekti.

Sellisel juhul tuleks klassi loomisel talle tarvilik klass eraldi ette anda:

php:
  1. <?php
  2. class Session {
  3.     private db;
  4.     function __construct($db) {
  5.         $this->db = $db;
  6.     }
  7. }
  8.  
  9. $db = new MysqlDB();
  10. $sess = new Session($db);
  11. ?>


Staatiliste meetodite kasutamine on aga tee mis viib Objekt-Orienteeritud Programmeerimise juurest tagasi protsedureelse programmeerimise juurde. Võtkem näiteks see eelpool toodud kood:

php:
  1. <?php
  2. class Mysql {
  3.     public static function Init($host, $username, $password, $dbname) {
  4.          mysql_connect($host, $username, $password);
  5.          mysql_select_db($dbname);
  6.     }
  7.     public static function Query($sql) {
  8.         return mysql_query($sql);
  9.     }
  10. }
  11. ?>


See pole midagi muud kui lihtsalt OOP-kujule maskeerunud tavalised funktsioonid:

php:
  1. <?php
  2. function Mysql_Init($host, $username, $password, $dbname) {
  3.     mysql_connect($host, $username, $password);
  4.     mysql_select_db($dbname);
  5. }
  6. function Mysql_Query($sql) {
  7.     return mysql_query($sql);
  8. }
  9. ?>


OOP puhul tasub meelest pidada, et olulised ehituskivid on siiski objektid, mitte klassid (muidu oleks meil klass-orienteeritud programmeerimine).

_________________
Mõistus otsas? Pane pinusse...
Kommentaarid: 24 loe/lisa Kasutajad arvavad:  :: 0 :: 1 :: 23
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
inzinz
HV kasutaja

liitunud: 26.01.2005




sõnum 07.01.2009 21:48:40 vasta tsitaadiga

No, see static ikkagi komplekteerib ühte kohta/klassi kokku kõik asjad, samamoodi lisad klassi sisse static muutujaid jne, singleton tüüpi klasside puhul (mida ainult üks tehaks töötamise ajaks ja mida mitmetes kohtades kasutatakse) on selline lähenemine kõvasti mugavam.

Miks soovitasin seda on järgmine:
1) Mysql ühendusi julgeks pakkuda et tehakse 99% php veebilehtede puhul ainult üks ainult ühte andmebaasi (ehk kui kasutatakse mysql klassist tehtud objketi, siis seda tehakse ainult üks)
2) Antud ühendust/objekti on vaja saada kasutada suvalistes klassides/funktsioonides nii, et oleks mugav ja võimalikult optimaalse kirjutamisvaevaga, kiirendades niimoodi arendamist.
3) Et seda ühteainsat objekti igal pool kasutada on peamiselt kaks lähenemist:
a) $db nimeline globaalne muutuja, mille kasutamiseks peab igasse vastava funktsiooni algusesse kirjutada "global $db;"
b) teha mingi klass staatilise funktsiooniga mis tagastab seda ühte ja sama objekti, eemaldades niimoodi vajaduse kirjutada "global $db;" kuid toob kaasa endaga stiili: MysqlFactory::getInstance()->Query();
Mõlemad kasutusviisid sisaldavad endas üleliigse koodi dubleerimist paljudesse kohtadesse mis on tuntud ka kui
tsitaat:

halb programmeerimispraktika

icon_razz.gif

Selline static stiilis lähenemine singleton klasside jaoks on minu meelest igal juhul etem, kuna ei pea kusagile kirjutama "global $db;" ning MysqlFactory::getInstance()->Query() ja selle muud variatsioonid ( Mysql::Instance()->Query(), $this->db->Query() ) lühenevad märgatavalt, andes tulemuseks Mysql::Query() jne. Kui klassi nimetust vähendada saab ka viia kujule Db::Query()

Lõpptulemuseks on lahendus, mis väänab veidike objektorienteeritud progemise ideaale, säilitades samal ajal ühtseks klassiks komplekteerimise efekti, ning mis kõige olulisem: muudab programmeerija elu edaspidi kordades lihtsamaks üleliigse koodi kirjutamise vähendamise arvelt.
Aga selline lähenemine on ainult siis mõttekas, kui on miski objekt, mida terve koodi töötamise ajal on alati üks ja ainult üks, muudel juhtudel ei saa seda lähenemist kasutada.

Üldiselt maitse asi kas kasutada nii või ei kuskil olukorras, aga minu meelest natuke painutatud ideoloogia ja mugavam progemine kaalub iga kell üle ideoloogia 100% järgimise ja vaevalisema progemise.
Kuna niikuinii index.php's olev esimene "require_once 'fail.php';" rikub OOP põhitõdesid, siis ei saagi täielikku ideaalset OOP koodi teha icon_razz.gif

_________________
Upload.ee - eestimaine failiupload
Kommentaarid: 4 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 4
tagasi üles
vaata kasutaja infot saada privaatsõnum
keevitaja
AM 10 aastat
keevitaja

liitunud: 05.11.2001




sõnum 07.01.2009 22:57:43 vasta tsitaadiga

selle staticuga vist nii ei õnnestu? igatahes algul panin classi Sstatic kõik functionid staticucs ja siis hiljem Sstatic:: . Igatahes andis errorit! Ehk tegin midagi valesti. Selliselt töötab ilusti:

php:
  1. <?php
  2. class Sstatic
  3. {
  4.         public function fun1($entry)
  5.         {
  6.                 $this->entry = $entry .' ja lisa!';
  7.         }
  8.        
  9.         public function fun2()
  10.         {
  11.                 return strtoupper($this->entry);
  12.         }
  13. }
  14.  
  15. class Klass
  16. {
  17.         private $first;
  18.        
  19.         function __construct($first)
  20.         {
  21.                 $this->first = $first;
  22.         }
  23.        
  24.         public function fun3($entry)
  25.         {
  26.                 $this->first->fun1($entry);
  27.         }
  28.        
  29.         public function fun4()
  30.         {
  31.                 print $this->first->fun2($this->first->entry);
  32.         }
  33. }
  34.  
  35. $static = new Sstatic;
  36.  
  37. $obj = new Klass($static);
  38.  
  39. $obj->fun3('See on asi');
  40. $obj->fun4();
  41.  
  42. ?>
icon_confused.gif

viimati muutis keevitaja 07.01.2009 23:11:47, muudetud 3 korda
Kommentaarid: 51 loe/lisa Kasutajad arvavad:  :: 1 :: 3 :: 40
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
inzinz
HV kasutaja

liitunud: 26.01.2005




sõnum 07.01.2009 23:24:15 vasta tsitaadiga

Siis tegid miskit valesti
proovi kas nii töötab

<?php
class Sstatic {
    public static function TeeMidagi() {
        echo "staatiline funktsioon tegi midagi";
    }
}

class Teineklass {
    public function Test() {
       Sstatic::TeeMidagi();
    }
}

$obj = new Teineklass();
$obj->Test();

?>

Selline peaks see kasutamine välja nägema ning antud koodi tulemusena peaks väljastatama string "staatiline funktsioon tegi midagi"

staatilist klassi ei peagi teisele klassile edasi andma, vaid kasutadki nii Staatiliseklassinimi::funktsioonimimi($parameeter);

Kui see kood töötab ja ideest aru saad, siis saad edasi katsetada juba, aga äkki näitad ka mis koodi ennem täpsemalt proovisid mis errorit andis ?

_________________
Upload.ee - eestimaine failiupload
Kommentaarid: 4 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 4
tagasi üles
vaata kasutaja infot saada privaatsõnum
keevitaja
AM 10 aastat
keevitaja

liitunud: 05.11.2001




sõnum 07.01.2009 23:43:09 vasta tsitaadiga

vaata selle Sstatic sees jookseb mõlemas fn-s muutuja $this->entry, mida hiljem Klassist väljakutsutavad fn-d kasutavad. kuidas seda staticuga teha?

php:
  1. <?php
  2. class Sstatic
  3. {
  4.         public static function fun1($entry)
  5.         {
  6.                 $this->entry = $entry .' ja lisa!';
  7.         }
  8.        
  9.         public static function fun2()
  10.         {
  11.                 return strtoupper($this->entry);
  12.         }
  13. }
  14.  
  15. class Klass
  16. {
  17.         public function fun3($entry)
  18.         {
  19.                 Sstatic::fun1($entry);
  20.         }
  21.        
  22.         public function fun4()
  23.         {
  24.                 SStatic::fun2(Sstatic::entry);
  25.         }
  26. }
  27.  
  28. $obj = new Klass();
  29.  
  30. $obj->fun3('See on asi');
  31. $obj->fun4();
  32.  
  33. ?>


nagu ma hetkel aru saan, siis static funtsioone saab klassist lihtsalt välja tuua ilma et nad omaks seoseid teste samas klassis olevat funktsioonidega
Kommentaarid: 51 loe/lisa Kasutajad arvavad:  :: 1 :: 3 :: 40
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
näita postitusi alates eelmisest:   
uus teema   vasta Tarkvara »  Programmeerimine »  PHP5 OOP küsimused mine lehele 1, 2, 3, 4  järgmine
[vaata eelmist teemat] [vaata järgmist teemat]
 lisa lemmikuks
näita foorumit:  
 ignoreeri teemat 
sa ei või postitada uusi teemasid siia foorumisse
sa ei või vastata selle foorumi teemadele
sa ei või muuta oma postitusi selles foorumis
sa ei või kustutada oma postitusi selles foorumis
sa ei või vastata küsitlustele selles foorumis
sa ei saa lisada manuseid selles foorumis
sa võid manuseid alla laadida selles foorumis



Hinnavaatlus ei vastuta foorumis tehtud postituste eest.