Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Skrypt modelu
Forum PHP.pl > Inne > Oceny
daniel1302
Witam, pisałem skrypty dla niejakiego Mariusza na tym forum znanego jako zlotownia. Ale po jego ostatnim zachowaniu postanawiam udostpnić skrypt do publicznego użytku i przy okazji do oceny.
  1. <?php
  2. /******************************************
  3.  *Autor: daniel1302
  4.  *Data Utworzenia: 26.08.2009
  5.  *
  6.  *Klasa ma za zadanie nawiązać połączenie
  7.  *z bazą danych, wykonywać na niej różnego
  8.  *rodzaju operacje, ujednolicać strukturę.
  9.  *Jest to głowna(klasa matka) klasa dla
  10.  *warstwy biurowej. Aplikacja kożysta z
  11.  *zwykłych funkcji bazy danych.
  12. ******************************************/
  13.  
  14.  
  15. Abstract Class Model
  16. {
  17. /**
  18. *Definicja dostępnych opcji
  19. **/
  20. protected $select = 1,
  21. $update = 1,
  22. $delete = 1,
  23. $add = 1;
  24.  
  25. protected $allFields;
  26. /****************************************
  27. *Metoda magiczna pozwoli na odczytanie
  28. *wartości z bazy danych.
  29. *
  30. *$var- Pole do odczytania
  31. ****************************************/
  32. public function __get($var)
  33. {
  34. if (isset($this -> structure[$var]) && isset($this -> allFields))
  35. return $this->allFields[$this -> structure[$var]];
  36. else
  37. return $var;
  38. }
  39.  
  40. /****************************************
  41. *Nawiązywanie połączenia z bazą danych
  42. ****************************************/
  43. public function __construct()
  44. {
  45. Mysql_Connect::getInstance('localhost', 'root', '', 'test');
  46. }
  47.  
  48. /****************************************
  49. *Funkcja zamienia pola z uniwersalnych na
  50. *te z bazy danych.
  51. *
  52. *$parms - Parametry do przetwozenia
  53. ****************************************/
  54. public function prepareExpression($parms)
  55. {
  56. return preg_replace_callback('/#{1}([a-z0-9_\-]+)/i', array($this, 'prepareExpression_callback'), $parms);
  57.  
  58. }
  59. private function prepareExpression_callback($matches)
  60. {
  61. return $this->structure[$matches[1]];
  62. }
  63.  
  64. /****************************************
  65. *Funkcja posłuży do logowania błędów
  66. ****************************************/
  67. protected function error()
  68. {
  69. echo date('Y-m-d H:i:s').': DB_ERROR('.mysql_errno().') '.mysql_error();
  70. }
  71.  
  72. /****************************************
  73. *Funkcja odpowiada za pobranie pólz bazy
  74. *danych.
  75. *
  76. *$fields- Pola do pobrania
  77. *$parms- Parametry warunku
  78. ****************************************/
  79. public function select($fields = null, $parms = null)
  80. {
  81. //Sprawdz dostęp
  82. if ($this -> select == 0)
  83. return false;
  84.  
  85. //Utwórz warunek
  86. if (!is_null($parms))
  87. $parms = $this -> prepareExpression($parms);
  88.  
  89. //Wybierz pola do wybrania z bazy
  90. $fields = (is_null($fields)) ? '*' : $this -> prepareExpression($fields);
  91.  
  92. //Właściwe zapytanie
  93. $result = mysql_fetch_assoc(mysql_query('SELECT '.$fields.' FROM '.$this -> table.' WHERE '.$parms)) or $this-> error();
  94. return $result;
  95. }
  96.  
  97. /****************************************
  98. *Funkcja odpowiada za edytowanie pól
  99. *
  100. *$fields- Pola do pobrania
  101. *$parms- Warunek dodania
  102. ****************************************/
  103. public function update(Array $fields, Array $parms)
  104. {
  105. if ($this -> update == 0)
  106. return false;
  107.  
  108. //Podlicz ilość pól do uaaktualnienia i zweryfikuj z warunkami
  109. $fieldsCount = count($fields);
  110. if ($fieldsCount != count($parms))
  111. return false;
  112.  
  113.  
  114. for($i=0; $i<$fieldsCount; $i++)
  115. {
  116. //Pzekonwertuj nazwy pól z jednolitych na rzeczywiste
  117. $_field = $this -> prepareExpression($fields[$i]);
  118. //Utwórz wyrażenie warunkowe
  119. $_parms = $this -> prepareExpression($parms[$i]);
  120.  
  121. mysql_query('UPDATE '.$this->table.' SET '.$_field.' WHERE '.$_parms)or $this-> error();
  122. }
  123. }
  124.  
  125. /****************************************
  126. *Funkcja usuwająca rekordy z bazy danych
  127. *
  128. *$parms- Warunek usunięcia
  129. ****************************************/
  130. public function delete($parms)
  131. {
  132. if ($this->delete == 0)
  133. return false;
  134.  
  135. //Przygotuj warunek po WHERE
  136. $parms = $this -> prepareExpression($parms);
  137.  
  138. //Właściwe zapytanie
  139. mysql_query('DELETE FROM '.$this -> table.' WHERE '.$parms)or $this -> error();
  140. }
  141.  
  142. /****************************************
  143. *Funkcja dodająca rekordy z bazy danych
  144. *
  145. *$fields- Pola
  146. *$value- Wartości pól
  147. ****************************************/
  148. public function add($fields, $value)
  149. {
  150. if ($this -> add == 0)
  151. return false;
  152.  
  153. //Właściwe zapytanie
  154. mysql_query('INSERT INTO '.$this -> table.'('.$this -> prepareExpression($fields).') VALUES ('.$value.')')or $this->error();
  155. }
  156. }
  157.  
  158. /******************************************
  159.  *Autor: daniel1302
  160.  *Data Utworzenia: 26.08.2009
  161.  *
  162.  *Jedynym zadaniem klasy jest nawiązanie
  163.  *połączenie z bazą danych
  164. ******************************************/
  165. {
  166. /**
  167. *Instancja
  168. **/
  169. static private $instance = null;
  170.  
  171. /**
  172. *Konstruktor nawiąże połączenie
  173. **/
  174. public function __construct($host, $user, $pass, $db_name)
  175. {
  176. $db = mysql_pconnect($host, $user, $pass);
  177. $_db = mysql_select_db($db_name);
  178. return $_db;
  179. }
  180.  
  181. /**
  182. *Impletacja Singletunu- Zapobiegnie wielokrotnej próbie nawiązania połączenia przy wielu modelach
  183. **/
  184. public static function getInstance($host, $user, $pass, $db_name)
  185. {
  186. if (is_null(self::$instance))
  187. self::$instance = new Mysql_Connect($host, $user, $pass, $db_name);
  188. else
  189. return self::$instance;
  190. }
  191. }




Przykładowy model
  1. Class Player_Model extends Model
  2. {
  3. //Nazwa Tabeli
  4. protected $table = 'players';
  5. //Struktura
  6. public $structure;
  7. public function __construct()
  8. {
  9. parent::__construct();
  10. //Ujednolicamy dane.
  11. $this -> structure = array(
  12. 'id' => 'player_id',
  13. 'name' => 'player_name',
  14. 'gold' => 'player_gold'
  15. );
  16. //Tworzymy gracza
  17. $this -> add('#id, #name', '1, \'Tyranus\'');
  18. //Ustalamy zmienną allFields dla __get()
  19. $this -> allFields = $this -> select('*', '#id=1');
  20. //Odczytujemy z zmiennej $this -> allFields funkcją __get()
  21. echo $this -> name;
  22. //Dodajemy graczowi 100 złota a drugiemu zmieniamy mu nick
  23. $this -> update(array('#gold=#gold+100', '#name=\'Daniel1302\''), array('#id=1', '#id=2'));
  24. //Usuwamy gracza
  25. $this -> delete('#id=1');
  26. }
  27. }


Jeśli w bazie zmienimy nazwe tabeli to zmieniamy $this->table, jeśli nazwę pola to zmieniamy $this->structure. W zapytaniach podajemy klucz z $this -> structure poprzedzony #(hash).

Proszę o ocene oraz komentarze i propozycje zmian.
Crozin
1) Jaki jest cel istnienia klasy MySQL_Connect? Co ona niby robi?
2)
  1. <?
  2. $a = new MySQL_Connect();
  3. $b = new MySQL_Connect();
  4. $c = new MySQL_Connect();
  5. $d = new MySQL_Connect();
Coś Ci ten singleton nie wyszedł bo powyższy kod zadziała.
3) Jako "klasa do obsługi do bazy" to strasznie słabe to będzie
4) Na moje oko to wysypie się przy pierdole typu:
Kod
#name='Cro#zin'
wookieb
Cytat
kożysta
ja p.....


Nie korzystasz ze składni phpdoca do opisywania metod.

daniel1302
Crozin:
1.Klasa ta zapobiega wielokrotnemu wywołaniu metody mysql_connect()
2. Zmień dostęp do __construct na private
3. Nie jest to klasa do obsługi bazy danych, lecz klasa Abstrakcyjna modelu
4. Masz jakąś propozycje aby temu zapobiec?
Masz jakaś propozycja jak
wookieb
Cytat(daniel1302 @ 29.08.2009, 13:49:56 ) *
Crozin:
1.Klasa ta zapobiega wielokrotnemu wywołaniu metody mysql_connect()

Właśnie, że nie. Poza tym __construct nie może cokolwiek zwracać.

Cytat
3. Nie jest to klasa do obsługi bazy danych, lecz klasa Abstrakcyjna modelu

Klasa abstracyjna modelu obsługująca bazę danych.

Dlaczego wszyscy myślą, że model to interfejs do obsługi bazy danych? A jak mam dane w plikach?
Crozin
1) A na jaką cholerę mam wywoływać w ogóle mysql_connect()?
2) Konstruktor to nie wszystko, nadal można tworzyć kolejne instancje przez kopiowanie już istniejących.
3) Tak się zastanawiam po co w ogóle ta klasa. Jeżeli model ma korzystać z bazy danych to niech sobie z jakiegoś kontekstu (czy czegoś) pobierze obiekt i na nim operuje. Modele nie ograniczają się wyłącznie do lokalnej bazy danych...
4) Tak... nie używać czegoś takiego, tylko skorzystać np. z PDO, które przynajmniej da podstawowe bezpieczeństwo oraz nie wysypie się z powodu wewnętrznych błędów.
wookieb
Cytat(Crozin @ 29.08.2009, 14:49:46 ) *
1) A na jaką cholerę mam wywoływać w ogóle mysql_connect()?

Oj nawet nie wiesz jakie to jest dobre rozwiązanie chociażby w koncepcji Inversion Of Control.
daniel1302
Witam, teraz całkiem mi pomieszaliście.
Po kolei, na tym forum wyczytałem, że najlepszym przykładem jest model Agavi.
  1. abstract class AgaviModel implements AgaviIModel
  2. {
  3. protected $context = null;
  4.  
  5. public final function getContext()
  6. {
  7. return $this->context;
  8. }
  9.  
  10. public function initialize(AgaviContext $context, array $parameters = array())
  11. {
  12. $this->context = $context;
  13. }
  14.  
  15. public function __sleep()
  16. {
  17. $this->_contextName = $this->context->getName();
  18. $arr = get_object_vars($this);
  19. unset($arr['context']);
  20. return array_keys($arr);
  21. }
  22.  
  23. public function __wakeup()
  24. {
  25. $this->context = AgaviContext::getInstance($this->_contextName);
  26. unset($this->_contextName);
  27. }
  28. }


Ale jak mam tutaj wpisać kod aby był elastyczny, np: Proszę o podanie przykładu jak wkleić kod inicjujący obsługę DB i XML.

Mam zrobić 2 klasy(DB, XML), posiadające takie same opcje(select, add, update) czy jak?
W przykładowych modelach niema momentu pobierania danych, są już gotowe tablice
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.