Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Problem z dziedziczeniem
Forum PHP.pl > Forum > PHP > Object-oriented programming
asqwe
Witam,

mam problem z dziedziczeniem w PHP5. Konkretnie chodzi o wywoływanie metod klas bazowych. Mam dwie klasy - sql i sesssion. Chciałbym, aby klasa session korzystała z klasy sql przy operacjach na bazie mysql.



Klasa sql:
Kod
       <?
       class sql {
      
         public $_res;
         public $_sql;
         public function __construct() {
        
           // otwiera połączenie z bazą
          
           if(!$this->_sql) {
             include_once("config.php");
            
             @ $this->_sql = new mysqli($HOST, $USER, $PASS, $DB);
             @ $this->_sql -> query("SET NAMES latin2");
            
            
             if (mysqli_connect_errno() != 0){
                  throw new Exception(mysqli_connect_error());
             }
            
           }
        
         }
      
         public function query($zapytanie) {
        
           // zwraca wartość mysqli
          
           $this->_res = $this->_sql->query($zapytanie);
           $ile = $this->_res -> num_rows;
          
           if (mysqli_errno() != 0) {
               throw new Exception(mysqli_error());
           }
        
           return $this->_res;
        
         }
  
     public function numRows() {
       return $this->_res->num_rows;
     }
    
        
      
       }
     ?>



Klasa sesssion
Kod
       <?
       include_once("sql.class.php");
       session_start();
       class session extends sql
       {
         private $sessionTime = 300; // czas po jakim wylgoować nieaktywnych
         private $logs = array(); // tablica logów
      
         public function __construct()
         {
        
           parent::query("DELETE FROM sessions WHERE last < CURRENT_TIMESTAMP()+".$this->sessionTime); // wylogowuje nieaktywnych
      
           // sprawdza czy sesja jest nadal ważna
           if($_SESSION[auth] == 1 && strlen($_SESSION[token]) == 16 && is_int($_SESSION[id]) && $_SESSION[ip] == $_SERVER[REMOTE_ADDR])
           {
             parent::query("SELECT * FROM `sessions` WHERE `token` = '$_SESSION[token]' AND `id` = '$_SESSION[id]' AND `ip` = '$_SESSION[ip]'");
             if(parent::numRows != 1) $_SESSION[auth] = FALSE;
             else echo "Jesteś zalogowany
       ip: $_SESSION[ip]";
           }
           else
           { echo("Nie jesteś zalogowany!"); $_SESSION[auth] = 0; }
         }
  
     public function addLog($action)
     { array_push($this->logs,strip_tags($action)); }
    
     public function __destruct()
     {
       $query = "INSERT INTO logs (`action`) VALUES ";
       foreach($this->logs as $logs)
       { $query .= "('$logs'), "; }
       parent::query(substr($query,0,-2).";");
     }
   }
       ?>


Plik w którym testuję klasę:
Kod
<?
session_start();
include_once("session.class.php");

try {

   $obj = new session();
   $obj -> addLog("1");
   $obj -> addLog("<b>2</b>");
   $obj -> addLog("3");
  
}

catch(Exception $error) {

   echo("<p class='error'>Wystąpił problem: ".$error->GetMessage()."
Plik: ".$error->GetFile()."
Wierz: ".$error->GetLine()."</p>");
   include("foot.php");
   exit;
  
}

include("foot.php");
?>
LBO
Nie dziedzicz sesji po SQL - mija się to z paradygmatem obiektowości. Użyj w zamian agregacji.
  1. <?php
  2. $sql = new sql();
  3.  
  4. //inne operacje
  5.  
  6. $session = new session();
  7. $session->setSQL($sql); // zapisz gdzieś w środku klasy i używaj tej instancji sql do zapytań.
  8. ?>


Nie mówię już nic, że genralnie to jest xle zaprojektowanie... ale na początek wystarczy.

Pozdrawiam, Alan
elemek
przeciazyles konstruktor i dlatego funkcja __construct w klasy sql nie jest wywolywana.

dopisz parent::__construct() przed parent::query w konstruktorze session
asqwe
Cytat(LBO @ 22.08.2008, 10:46:10 ) *
Nie dziedzicz sesji po SQL - mija się to z paradygmatem obiektowości. Użyj w zamian agregacji.
Nie mówię już nic, że genralnie to jest xle zaprojektowanie... ale na początek wystarczy.


Byłbym bardzo wdzięczny, jeśli wskazałbyś błędy w projektowaniu aplikacji smile.gif
LBO
Proszę bardzo.

Wyspecjalizowana klasa SQL - źle. Powinieneś mieć klasę abstrakcyjną (lub interfejs) który jasno określi jakie metody powinny mieć klasy z tej rodziny (rodziny, bo równie dobrze, może być to MySQL, PostrgeSQL, SQLite) i dopiero klasy dziedziczące powinny implementować swoje funkcje związane z konkretną bazą (zapytania, łączenie, etc).
Przyczepiłbym się do samego faktu, że napisałeś taką klasę, skoro istnieje PDO" title="Zobacz w manualu PHP" target="_manual.

Dalej: session - znów podobnie możesz mieć sesję, która korzysta z plików, z bazy lub z czegoś innego.
Largo
Witam,

Może ja tu przedmówcę wyjaśnię podając kod:

Klasa abstrakcyjna:

  1. <?php
  2.  
  3. abstract class SQL
  4. {
  5. public $cid;
  6. public $host;
  7. public $user;
  8. public $pass;
  9.  
  10. abstract protected function connect($host, $user, $pass);
  11. abstract protected function query($query, $limit);
  12. abstract protected function fetchRow();
  13.  
  14. public function __construct($host, $user, $pass, $auto_select = TRUE)
  15. {
  16. if ($auto_select === TRUE)
  17. {
  18. connect();
  19. select_base();
  20. }
  21. else
  22. {
  23. connect();
  24. }
  25. }
  26. }
  27.  
  28. ?>


Klasa potomna:

  1. <?php
  2.  
  3. class MySQL_SQL extends SQL
  4. {
  5. public function query($query, $limit)
  6. {
  7. //Tu podajesz własną definicję zapytanie dla MySQL
  8. }
  9.  
  10. public function connect($host, $user, $pass)
  11. {
  12. //Dokładnie to samo co na górze.
  13. }
  14. }
  15.  
  16. ?>


Jak widzisz sama klasa abstrakcyjna nie robi prawie nic ( chociaż możesz w niej napisać metody wspólne dla wszystkich potomków, np. dla Zwierzę wspólne jest WC :-P i wykorzystać je w klasie potomnej ) i nie moze też mieć sama w sobie instancji ( $base = new SQL(); ), ona tylko uogólnia klasy potomne.

Życzę powodzenia w dalszej nauce OOP :-)
Pozdrawiam!
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.