Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Czy to jest poprawne - w duchu obiektowości?
Forum PHP.pl > Forum > PHP > Object-oriented programming
Aztech
Zacząłem niedawno pisać na poważnie (w końcu praca duplomowa) w php5 i chciałbym się spytać czy to co napisałem, jest w pełni w duchu obiektowości. Może widzicie tam jakieś błędy, może macie jakieś wskazówki. Za wszelkie rady, spostrzeżenia, w szczególności te bardzo krytyczne, będę niezmiernie wdzięczny.

Gwoli wyjaśnienia, klasa ta ma odpowiadać za obsługę użytkownika:
(*) dodawać
(*) usuwać
(*) uaktualniać
(*) parsować poprawność wprowadzonych danych
itp.

A więc jeszcze raz proszę o jak najwięcej uwag i krytyki (ew. pochwały też przyjmuję biggrin.gif)


  1. <?php 
  2.  
  3.  
  4. /*
  5.     UWAGA: wszystkie zapytanie sql sformatować odpowiednio dla adodb
  6. */
  7.  
  8. require_once("../core/adodb/adodb.inc.php");
  9.  
  10. class TUser {
  11.     private $user_id=-1;
  12.     private $nick ="";
  13.     private $name= "";
  14.     private $group_id=0;
  15.     private $password="";
  16.     private $password_crypt="";
  17.     private $email="";
  18.     private $gg="";
  19.     private $photo="";
  20.     private $description="";
  21.     private $phone="";
  22.     private $last_error="";
  23.     private $is_error=0;   //0 - no error, 1 - error
  24.  
  25. ################################## need to update all validation functions #####
    ##############################
  26.  
  27. /********************************************************************************
    *****    
  28.                         VALIDATE FUNCTIONS                    
  29. ********************************************************************************
    *****/
  30.  
  31.     public function validateName($name) {
  32.         // validate if name is correct, name have 2 words which begin with uppercase and s
    pace beetween of them
  33.         if (ereg("^[A-z](a-zA-Z/-)*( A-Za-z/-)*",$name)) {
  34.                $this->unsetError();
  35.                return true;           
  36.         }
  37.         else {
  38.             $this->last_error = "NO_VALID_NAME";
  39.             $this->setError();
  40.             return false;
  41.         }       
  42.     }
  43.     
  44.     public function validateEmail() {
  45.         //validate if email is correct
  46.         if (eregi("^([a-z0-9_-.]{1,25})@([a-z0-9_-.]){1,25}$",$this->$email)){
  47.                $this->unsetError();
  48.                return true;           
  49.         }
  50.         else {
  51.             $this->last_error = "NO_VALID_EMAIL";
  52.             $this->setError();
  53.             return false;
  54.         }
  55.     }
  56.     
  57.     public function validatePassword($pass) {
  58.         //6-25 signs, one big letter and one number        
  59.         if (ereg("[A-Za-z0-9]")) {
  60.                $this->setError();
  61.                return true;           
  62.         }
  63.         else {
  64.             $this->last_error = "NO_VALID_PASSWORD";
  65.             $this->setError();
  66.             return false;
  67.         }
  68.     }
  69.     
  70. /********************************************************************************
    *****    
  71.                         COMPARE FUNCTIONS                   
  72. ********************************************************************************
    *****/
  73.  
  74.     public function comparePassword($value="") {
  75.         if ($this->password == $value) {
  76.             $this->unsetError();            
  77.             return true;            
  78.         }
  79.         else {
  80.             $this->last_error = "PASSWORD_NOT_SAME";
  81.             $this->unsetError();
  82.             return false;
  83.         }           
  84.     }    
  85.  
  86. /********************************************************************************
    *****    
  87.                         GET FUNCTIONS                    
  88. ********************************************************************************
    *****/
        
  89.     
  90.     public function getUserInfo(){
  91.         return $this;
  92.     }
  93.  
  94. /********************************************************************************
    *****    
  95.                         SET FUNCTIONS                    
  96. ********************************************************************************
    *****/
        
  97.  
  98.     public function setError(){
  99.         $this->is_error = 1;
  100.     }
  101.     
  102.     public function unsetError(){
  103.         $this->is_error = 0;
  104.     }
  105.  
  106.     public function setUserID($value="") {
  107.         $this->user_id = $value;
  108.     }
  109.     
  110.     public function setNick($value="") {
  111.         $this->nick = $value;
  112.     }
  113.     
  114.     public function setName($value="") {
  115.            $this->name = $value;
  116.     }
  117.     
  118.     public function setGroupID($value="") {
  119.            $this->group_id = $value;
  120.     }
  121.     
  122.     public function setPassword($value="") {
  123.            $this->password = $value;
  124.     }
  125.     
  126.     public function setEmail($value="") {
  127.            $this->email = $value;
  128.     }
  129.     
  130.     public function setGG($value="") {
  131.            $this->gg = $value;
  132.     }
  133.     
  134.     public function setPhoto($value="") {
  135.         $this->phone = $value;
  136.     }
  137.     
  138.     public function setDescription($value="") {
  139.            $this->description = $value;
  140.     }
  141.     
  142.     public function setPhone($value="") {
  143.            $this->phone = $value;
  144.     }
  145.     
  146.     
  147.     public function setUserFromSQL($table){
  148.         //set user data using result form SQL query
  149.         $this->user_id          =   $table["id_user"];
  150.         $this->nick             =   $table["nick"];
  151.         $this->name             =   $table["name"];
  152.         $this->group_id         =   $table["name"];
  153.         $this->password         =   $table["password"];
  154.         $this->password_crypt   =   md5($table["password"]);
  155.         $this->email            =   $table["email"];
  156.         $this->gg               =   $table["gg"];        
  157.         $this->photo            =   $table["photo"];
  158.         $this->description      =   $table["description"];
  159.         $this->phone            =   $table["phone"];
  160.         $this->last_error       =   "";
  161.         $this->is_error         =   "0";    //no error
  162.     }
  163.        
  164.     public function __construct() {
  165.         $this->user_id          =   "-1";
  166.         $this->nick             =   "";
  167.         $this->name             =   "";
  168.         $this->group_id         =   "0";
  169.         $this->password         =   "";
  170.         $this->password_crypt   =   "";
  171.         $this->email            =   "";
  172.         $this->gg               =   "";        
  173.         $this->photo            =   "";
  174.         $this->description      =   "";
  175.         $this->phone            =   "";
  176.         $this->last_error       =   "";        
  177.         $this->is_error         =   "0";    //no error
  178.     }
  179.     
  180.     public function clearrData() {
  181.         $this->__construct();
  182.     }
  183.  
  184. /********************************************************************************
    *****    
  185.                         SET FUNCTIONS                    
  186. ********************************************************************************
    *****/
     
  187.  
  188.     public function findAllGroupsSQL(&$groups) {
  189.         //fing all groups where belong user
  190.         //if user is set
  191.         if ($this->user_id != "-1") {
  192.             /*
  193.             $sql =   " SELECT user_id, group_id, id_groups, name, moderator_id"
  194.                     ." FROM rbx_group_users LEFT JOIN rbx_groups"
  195.                     ." ON rbx_group_users.group_id = rbx_groups.id_groups"
  196.                     ." WHERE user_id = 3";            
  197.                     */
  198.         }
  199.         else {
  200.             $this->lastError="NO_USER";
  201.             $this->setError();
  202.             return false;
  203.         }
  204.     }
  205.     
  206.     public function userExistsSQL() {
  207.         //connectToADO($db);
  208.         $sql = "select email from rbx_username where email='".$this->email."'";
  209.         //$result = $db->Execute($sql);  
  210.         if (!$result->FieldCount())
  211.             return true;
  212.             else return false;        
  213.     }
  214.     
  215.     public function createUserSQL() {
  216.     //gdy uzytkownik nie istnieje
  217.         if (!$this->userExists()) {
  218.             //connectToADO($db);
  219.             $sql = "insert into 'rbx_user' ( 'id_user' , 'name' , 'pass' , 'email' , 'gg' , 'photo' , 'description' , 'phone' )".
  220.             " values ('', '".$this->name."', '".$this->password_crypt."', '".$this->email."', '".$this->gg."', '".$this->photo."', '".$this->description."', '".$this->phone."')";
  221.             //$result = $db->Execute($sql);          
  222.             $this->is_error = false;      
  223.         }
  224.         else {
  225.             $this->is_error = true;
  226.             $this->last_error = "USER_ALREADY_EXIST";
  227.         }
  228.     }           
  229.  
  230.     public function updateUserSQL() {    
  231.         //connectToADO($db);        
  232.             $sql = "update 'rbx_user'"
  233.             ." set 'name'=".$this->name.","
  234.             ." 'pass'=".$this->password_crypt.","
  235.             ." 'email'=".$this->email.","
  236.             ." 'gg'=".$this->gg.","
  237.             ." 'photo'=".$this->photo.","
  238.             ." 'description'=".$this->description.","
  239.             ." 'phone'=".$this->phone.","
  240.             ." 'pass'=".$this->password_crypt
  241.             ." WHERE 'id_user'=".$this->user_id;            
  242.         //$result = $db->Execute($sql);          
  243.         $this->is_error = false;      
  244.     }
  245.     
  246.     public function deleteCurrentUserSQL() {
  247.         //connectToADO($db);
  248.             $sql = "delete from 'rbx_user'"
  249.             ."WHERE user_id=".$this->user_id;
  250.         //result = $db->Execute($sql);
  251.         $this->is_error = false;
  252.     }
  253.     
  254.     public function deleteUserSQL($db) {
  255.         //connectToADO($db);
  256.             $sql = "delete from 'rbx_user'"
  257.             ."WHERE user_id=".$db->user_id;
  258.         //result = $db->Execute($sql);
  259.         $this->is_error = false;
  260.     }        
  261.     
  262.         
  263. }
  264.  
  265. ?>
Kinool
konstrukto nic szczegolnego nie robi wiec chyba zrobiles go tylko po to aby byl sad.gif

w metodzie validatePassword masz chyba blad bo zawsze wywoluje metode $this->setError();

co do samej obslugi bledow to nie wiem jak dalej chesz to implementowac ale zaluzmy ze ktos ma zla nazwe uzytkownika wiec ustawiasz u error na 1 ale maila ma dobrego wic wlasciwosc is_error bedzie zmieniona na 0 (brak bledu)

no i widze niekonsekwencje alebo uzywasz wartosci liczbowych albo boolenowskich smile.gif (1 czy true) zdecyduj sie wiem ze php jest bardzo tolerancyjne i odczyta 1 jako true ale to nie znaczy zeby robic takie "bledy"
dr_bonzo
Nie wiem czy masz taka metode (troche ich tam duuzo) validateUserData(), ktora wywoluje kazda z podmetod walidacji: validateEmail() itd. Jesli user ma byc dodany gdy WSZSYTKIE dane sa prawidlowe to przydadza ci sie wyjatki: gdy email jest zly validateEmail() wyrzuca wyjatek, validateUserData() go lapie i zwraca FALSE/wyjatek co oznacza ze dane usera nie sa prawidlowe.
Aztech
@Kinool: Faktycznie na samej górze jest 0 1 a potem true false - poprawię to.
Co do konstruktora, to pojawi tam się jeszcze parę rzeczy, m. in. to co zostało zaproponowane w tym wątku.
Co do validatePassword to masz absolutną rację

@bonzo: dobra sugestia - skorzystam

@all: Poprosiłbym jakieś sugestie co do obiektowaości, czy są jakieś niedociągnięcia, co można inaczej zrobić, ew czego nie robić.

Dzięki za dotychczasowe uwagi
krzysztof f.
Witam Aztech!

Więc zaczynamy.. zajmijmy się duchem obiektowości ; ).
Pierwsza zasada: każdy obiekt w systemie powinien mieć ściśle określoną odpowiedzialność, którą da się opisać jednym zdaniem. Powinien dostarczać implementacji jakiegoś zachowania lub struktury z dziedziny problemu. Jednym słowem musimy wystrzegać się tak zwanych god classes, przeciążonych nadmierną odpowiedzialnością i kodem.

W tej kwestii poradziłeś sobie nie najgorzej, ale też daleko od ideału. Przyjrzyjmy się odpowiedzialności klasy, którą potrzebujesz stworzyć. Będzie to prawdopodobnie klasa opisująca obiekt użytkownika w Twojej aplikacji. Obiekt taki ma identyfikować pojedynczego użytkownika i dostarczać niezbędnych poprawnych danych o nim. Ponadto obiekt taki ma być utrwalany w bazie danych. W tym miejscu powinno nasunąć się już pytanie, czy obiekt użytkownika powinien też odpowiadać za utrwalanie siebie w bazie danych. Zgodnie z architekturą wielowarstwową obiekt użytkownika należy do warstwy logiki biznesowej, a zapisywanie do bazy to już odpowiedzialność warstwy danych. Aby oddzielić zupełnie te dwie odpowiedzialności musielibyśmy się zająć pojęciem ORM, którego niewielki fragment znajdziesz w przykładowym rozdziale z PoEAA http://www.awprofessional.com/articles/article.asp?p=30661.

W twoim przypadku prawdopodobnie wystarczy prostsze rozwiązanie, które w zasadzie już zastosowałeś a nazywa się Active Record http://martinfowler.com/eaaCatalog/activeRecord.html. Jest wzorzec stosowany do tworzenia obiektów dziedziny, których struktura pokrywa się ze strukturą tabeli i które reprezentują pojedynczy rekord takiej tabeli. Oprócz podstawowej niewielkiej ilości logiki biznesowej, potrafią one utrwalać się w bazie danych.

Skoro padła już nazwa jakiegoś wzorca, to możemy być pewni, że część odpowiedzialności prawdopodobnie uda nam się wyłączyć do klasy bazowej. http://www.daholygoat.com/jaws/html/index....ction=Page&id=8

Więc ustaliliśmy już kwestie utrwalania danych http://patternshare.org/default.aspx/Home.MF.ActiveRecord , postanowiliśmy wyodrębnić klasę bazową. Teraz zastanówmy się nad metodą wydobywania danych i konkretyzacji obiektów. Aby odciążyć trochę klasę użytkownika, odpowiedzialność za wyszukiwanie obiektów w bazie należałoby wyodrębnić do oddzielnego obiektu. Przy okazji zastosujemy Separatek Interface http://patternshare.org/default.aspx/Home....aratedInterface ukrywając implementację przed kodem klienta. W praktyce kod klienta będzie wyglądał mniej więcej tak:

  1. <?php
  2. $oUser = $oUserFinder->findByName( 'Krzysztof' );
  3. $oUser->setNick( 'blazej' );
  4. $oUser->update();
  5.  
  6. //dla kolekcji obiektów
  7. $aUsers = $oUserFinder->findAll();
  8. foreach ( $aUsers as $oUser )
  9. {
  10.  echo $oUser->getName() . '<br />';
  11. }
  12. ?>


Poświęćmy jeszcze chwilę tworzeniu obiektów User. Nie podoba mi się, że pozwalasz tworzyć puste obiekty nie wykorzystując konstruktora. Poza tym konstruktor jest metodą wykorzystywaną tylko w momencie inicjacji obiektu, więc wywołanie go w metodzie TUser:: clearData() jest błędem. Musisz odpowiedzieć sobie na pytanie jakie dane wymagane są do prawidłowego funkcjonowania obiektu User i zadbać o ich inicjalizację w czasie konstruowania obiektu. Prawdopodobnie nie może istnieć użytkownik, który się jakoś nie nazywa i nie ma podanego e-maila (który jest w wielu miejscach aplikacji wykorzystywany do komunikacji z nim). Konkretyzacja obiektu powinna wtedy wyglądać tak:

  1. <?php
  2. $oNewUser = new User( 'Krzysztof', 'adres@email.pl' );
  3. ?>


O enkapsulacji pamiętasz, kolejna ważna zasada zgodna z duchem obiektowości ; ). Mamy wszystkie składowe jako prywatne. Odpowiednie metody ustawiające wartości. Dodałbym jeszcze metody do pobierania potrzebnych wartości albo zrobił pożytek z metody __call() dla zmniejszenia ilości kodu (chociaż biorąc pod uwagę przejrzystość interfejsu, może jednak nie). Metody walidujące zawarł bym przy odpowiednich seterach.

Sqle do modyfikowania rekordów zgonie ze wzorcem ActiveRecord zostają w klasie User. Wyszukujące wyłączamy. Dodajemy obiekt klucza stanowiący interpretację wzorca http://martinfowler.com/eaaCatalog/identityField.html, pilnujący tożsamości obiektów i powiązanych rekordów w bazie. Przy ładowaniu obiektów z bazy rejestrujemy je w IdentityMap http://martinfowler.com/eaaCatalog/identityMap.html dostępnej za pomocą jakiegoś rejestru, zabezpieczającej naszą aplikację przed wielokrotnymi odwołaniami do bazy danych i tworzeniem wielu instancji tego samego obiektu. Na koniec dodajemy kontrolę nad modyfikacją naszych obiektów w czasie ich życia i automatyczne utrwalanie zmian w bazie danych, za co odpowiedzialnością obarczamy „obiekt jednostki pracy”. Natomiast kolekcje obiektów obsługujemy (z wykorzystaniem opóźnionego ładowania) za pomocą specjalnego obiektu implementującego interfejs jednego z iteratorów SPL (tak jak to proponuje Matt Zandstra w „php 5 Objects, Patterns, and Practice” http://www.amazon.com/exec/obidos/ASIN/159...018931-2571322)

…i czy projektowanie obiektowe nie jest poezją!? : )

Dodatkowe uwagi:
1. Obsługa błędów w Twojej klasie jest fatalna. Skoro korzystasz z PHP5 i chcesz w pełni wykorzystywać jego możliwości obiektowe, to tak jak sugerowali przedmówcy powinieneś używać wyjątków. Dobra lektura na początek: http://www.zend.com/php5/articles/php5-exceptions.php
2. Pilnuj typu zmiennych, to że luźne typowanie w php daje dużo możliwości, nie zabezpiecza go przed wieloma problemami związanymi z tym. Ułatwieniem mogą być dobrze przygotowany standardy pisania kodu. Ja na przykład jak dodaje do nazw zmiennych przedrostek wskazujący jakiego typu jest zmienna. Poza tym lepiej dokumentuj swój kod, a w szczególności API. http://phpdoc.org/
3. Dodatkowo skoro PHP5 skoro nowy model obiektowy to sugeruję PDO jako abstrakcję dostępu do danych, zamiast AdoDb.

Tak to z grubsza mogłyby wyglądać zależności klas. Tobie pozostawiam implementację i życzę miłej zabawy.

chmolu
[ot]Krzysztofie, gdzieś ty się chował do tej pory? Don't stop, man smile.gif[/ot]
Aztech
Dzięki informacjom Krzysztofa wypożyczyłem sobie książkę i ostro czytam:
"Patterns Of Enterprise Application Architecture" (tak spolszczyli tytuł smile.gif) - Architerkuta systemów zarządzania przedsiębiorstwem - Wzorce projektowe). Póki co polecam!
ActivePlayer
troszeczke nie rozumiem schematu... albo z nazewnictwem sth wrong... UserFinder szuka usera tak ? w jaki sposob ma dostep do db ?
Ludvik
  1. <?php
  2. public function getUserInfo(){
  3. return $this;
  4. }
  5. ?>


A czemu to ma służyć?
1. Zwracasz referencję, którą klient już posiada, bo musi wywołać jakoś tą metodę...
2. Pola i tak są prywatne.

Najlepszy pomysł to utworzenie zestawu getterów, moim skromnym zdaniem.
krzysztof f.
Cytat(ActivePlayer @ 2005-11-29 19:47:09)
troszeczke nie rozumiem schematu... albo z nazewnictwem sth wrong... UserFinder szuka usera tak ? w jaki sposob ma dostep do db ?

Schemat tak jak napisałem jest tylko ogólną ilustracją. Słuszna uwaga, brakuje tam informacji o związku między klasą wyszukującą, a klasą połączenia z bazą danych. Oczywiście klasa UserFinder ma również dostęp do bazy danych i wywołuje polecenia SQL w celu wyszukania i zwrócenia obiektów użytkowników.

Związek ten powinien być oznaczony jako agregacja, ponieważ z reguły obiekt połączenia z bazą danych w konstruktorach klas AciteveRecord i Finder jest przypisywany do prywatnej właściwości i dostępny później w kontekscie klasy.
ActivePlayer
Cytat(krzysztof f. @ 2005-11-30 10:05:47)
Cytat(ActivePlayer @ 2005-11-29 19:47:09)
troszeczke nie rozumiem schematu... albo z nazewnictwem sth wrong... UserFinder szuka usera tak ? w jaki sposob ma dostep do db ?

Schemat tak jak napisałem jest tylko ogólną ilustracją. Słuszna uwaga, brakuje tam informacji o związku między klasą wyszukującą, a klasą połączenia z bazą danych. Oczywiście klasa UserFinder ma również dostęp do bazy danych i wywołuje polecenia SQL w celu wyszukania i zwrócenia obiektów użytkowników.

Związek ten powinien być oznaczony jako agregacja, ponieważ z reguły obiekt połączenia z bazą danych w konstruktorach klas AciteveRecord i Finder jest przypisywany do prywatnej właściwości i dostępny później w kontekscie klasy.

Jak ma sie sprawa jesli chodzi o pozniejszą zmianę struktury (chociazby nazw) w bazie danych ? bieganie po obiektach i zmiany ?
krzysztof f.
Active Record jak wspominałem jest najprostszym wzorcem związanym z dostępem obiektów do bazy i ściśle wiąże obiekt z bazą i jej strukturą. Zmiany w bazie danych wiążą się w tym przypadku ze zmianą kodu klasy User i UserFinder. Można i należy oczywiście zaimplementować wzorzec w taki sposób aby zmiany tego typu były jak najmniej uciążliwe.

Idąc dalej, ponieważ z założenia Rekordy Aktywne odpowiadają w pełni strukturze tabeli, nadają się doskonale do zastosowania generowania kodu samych klas.

Chociaż wzorzec jest bardzo prosty i powoduje wymieszanie logiki biznesowej, mimo to jest z powodzeniem używany. Według niektórych rewolucyjny framework do tworzenia aplikacji webowych, który w ostatnim czasie wprowadził wiele zamieszania i jest w tej chwili niezwykle popularny Ruby on Rails http://www.rubyonrails.com/, opiera swój model bardzo mocno na ActiveRecords. Jest tam generowanie kodu i nacisk na szybkie i elastyczne tworzenie aplikacji. Jak grzyby po deszczu powstają klony i porty Ruby on Rails w innych językach programowania. Nie omija to również php. Najpopularniejsze jest z pewnością Ciacho http://cakephp.org/.

P.S.
@chmolu dzięki za zachęte ...we never stop :)
kula
Witam wszystkich.

Przeczytalem te wszystkie oszerne opisy i czas dorzucic kilka groszy od siebie.

A wiec wykorzystanie ActiveRecords jest niesamowicie wygodne dla programisty ale tez ma swoje minusy, ponieważ podczas przetwarzania w aplikacji duzych ilosci danych tworzonych jest rowniez duzo instancji obiektow, co wplywa na wymagania i wydajnosc aplikacji. Odnosnie naszego przypadku ActiveRecords nadaja sie jak najbardziej.

Odnosnie tematu, ja bym posluzyl sie metoda rozbijania "bytów" na oddzielne obiekty. Wygladalo by to tak, ze uzytkownik reprezentowany by byl przez oddziena klase zawierajaca tylko jego dane (ewentualnie z walidacja). Nie wiem czy jest w PHP5 cos takiego jak "struct", ktore by sie idealnie nadawalo. By wykonywac operacje na bazie danych (dodawanie, aktualizacje itp uzytkownika) stworzyl bym kolejna klase, ktora w swoich metodach przyjmowala by objekt uzytkownika jako parametr.
Wg. mnie to jedno z najlepszych rozwiazan jesli chodzi o zachowanie "idealnej objektowosci". Popre to tylko takim małym przykładam: Co wie uzytkownik o bazie danych ?.

To takie moje skromne zdanie w tym topku.

Pozdrawiam.
NuLL
Cytat
Jak ma sie sprawa jesli chodzi o pozniejszą zmianę struktury (chociazby nazw) w bazie danych ? bieganie po obiektach i zmiany ?

Cos za cos niestety. Samego kodu za duzo zmieniac tak naprawde nie trzeba. Mozna sobie napisac cos ala genericObject czy typowy obiekt i po tym dziedziczyć poprostu. Cala klase z pierwszego posta mozna by powaznie skrocic korzystajac z tego co jest ponizej ( to tylko wzor pisany z palca, nie testowany czy cos )
  1. <?php
  2.  
  3. abstract class genericObject extends Object 
  4. {
  5. private 
  6. $myFields, $databaseFields, $loaded, $modified, $tupleId, $databaseTable, $keyName ;
  7.  
  8. public function __construct($tupleId=0)
  9. {
  10. $this->loaded=0;
  11. $this->tupleId=intval($tupleId);
  12. }
  13.  
  14. public function setDatabaseParams($table,$key)
  15. {
  16. $this->databaseTable=$table;
  17. $this->keyName=$key;
  18. }
  19.  
  20. public function forceLoaded()
  21. {
  22. $this->loaded=1;
  23. }
  24.  
  25. public function getField($name)
  26. {
  27. if($this->loaded==0)
  28. {
  29. $this->load();
  30. }
  31.  
  32. return $this->databaseFields[$name];
  33. }
  34.  
  35. public function getFields()
  36. {
  37. if($this->loaded==0)
  38. {
  39. $this->load();
  40. }
  41.  
  42. $fields=func_get_args();
  43.  
  44. $ret=array();
  45.  
  46. foreach ($fields as $field)
  47. {
  48. if(isset($this->databaseFields[$field])) $ret[$field]=$this->databaseFields[$field];
  49. }
  50.  
  51. return $ret;
  52. }
  53.  
  54. public function getAllFields()
  55. {
  56. if($this->loaded==0)
  57. {
  58. $this->load();
  59. }
  60.  
  61. return $this->databaseFields;
  62. }
  63.  
  64. public function setField($name,$value)
  65. {
  66. $this->myFields[$name]=$value;
  67. $this->modified=1;
  68. }
  69.  
  70. public function setFields($data)
  71. {
  72. if(is_array($data))
  73. {
  74. foreach ($data as $key=> $value)
  75. {
  76. $this->setField($key,$value);
  77. }
  78. }
  79. }
  80.  
  81. public function destroy()
  82. {
  83. if($this->tupleId)
  84. {
  85. $db=db::instance();
  86.  
  87. $db->execute("DELETE FROM ".$this->databaseTable." WHERE ".$this->keyName."=".$this->tupleId);
  88.  
  89. if($db->affectedRows()>0)
  90. {
  91. $this->loaded=0;
  92. return true;
  93. }
  94. return false;
  95. }
  96. }
  97.  
  98. public function getId()
  99. {
  100. return $this->tupleId;
  101. }
  102.  
  103. private function load()
  104. {
  105. $db=db::instance();
  106.  
  107. $this->databaseFields=$db->getRow("SELECT * FROM ".$this->databaseTable." WHERE ".$this->keyName."=".$this->tupleId);
  108.  
  109. $this->loaded=1;
  110.  
  111. $this->modifiedFields=array();
  112.  
  113. $this->modified=0;
  114. }
  115.  
  116. public function save()
  117. {
  118. $db=db::instance();
  119.  
  120. if($this->tupleId>0)
  121. {
  122. $db->update($this->databaseTable,$this->myFields,$this->keyName."=".$this->tupleId);
  123.  
  124. $ret=$db->affectedRows();
  125. }else
  126. {
  127. $insertId=$db->insert($this->databaseTable,$this->myFields);
  128. $ret=$insertId;
  129. $this->tupleId=$insertId;
  130. }
  131.  
  132. $this->databaseFields=$this->myFields;
  133. $this->databaseFields[$this->keyName]=$this->tupleId;
  134.  
  135. $this->myFields=array();
  136.  
  137. return $ret;
  138. }
  139. }
  140.  
  141. ?>
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.