Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Skrypt modelu
daniel1302
post
Post #1





Grupa: Zarejestrowani
Postów: 602
Pomógł: 30
Dołączył: 1.08.2007
Skąd: Nowy Sącz

Ostrzeżenie: (0%)
-----


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.
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 7)
Crozin
post
Post #2





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


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'


Ten post edytował Crozin 29.08.2009, 12:32:01
Go to the top of the page
+Quote Post
wookieb
post
Post #3





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




Cytat
kożysta
ja p.....


Nie korzystasz ze składni phpdoca do opisywania metod.



--------------------
Go to the top of the page
+Quote Post
daniel1302
post
Post #4





Grupa: Zarejestrowani
Postów: 602
Pomógł: 30
Dołączył: 1.08.2007
Skąd: Nowy Sącz

Ostrzeżenie: (0%)
-----


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
Go to the top of the page
+Quote Post
wookieb
post
Post #5





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




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?

Ten post edytował wookieb 29.08.2009, 13:13:43


--------------------
Go to the top of the page
+Quote Post
Crozin
post
Post #6





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


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.
Go to the top of the page
+Quote Post
wookieb
post
Post #7





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




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.


--------------------
Go to the top of the page
+Quote Post
daniel1302
post
Post #8





Grupa: Zarejestrowani
Postów: 602
Pomógł: 30
Dołączył: 1.08.2007
Skąd: Nowy Sącz

Ostrzeżenie: (0%)
-----


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
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 19.08.2025 - 11:48