Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: klasa sql
Forum PHP.pl > Inne > Oceny
kayman
w zasadzie 2 klasy bo connect jest oddzielnie

nie staram się wynaleźć koła na nowo tylko uprościć sobie robotę smile.gif

ale pewnie jest tu parę błędów więc oceniajcie

btw. PDO do mnie nie przemawia jakoś a może przyzwyczaiłem się do starego?

pozdrawiam

  1. <?php
  2.  
  3. class DBConnect {
  4.  
  5. private static $_instance;
  6. public static $db;
  7. private static $host = 'localhost';
  8. private static $user = 'root';
  9. private static $pass = '';
  10. private static $database = 'ukcrm';
  11.  
  12. private function __construct() {
  13. $this->connect();
  14. }
  15.  
  16. public function setConnect() {
  17. if (!isset(self::$_instance)) {
  18. self::$_instance = new DBConnect();
  19. }
  20. }
  21.  
  22. private static function connect() {
  23. self::$db = mysqli_connect(self::$host, self::$user, self::$pass, self::$database) or die('Connection fail');
  24. }
  25.  
  26. public function changeConnect($host, $user, $pass, $db) {
  27. if (isset(self::$_instance)) {
  28. mysqli_close(self::$db);
  29. self::$host = $host;
  30. self::$user = $user;
  31. self::$pass = $pass;
  32. self::$database = $db;
  33. self::connect();
  34. } else {
  35. self::$_instance = new DBConnect();
  36. self::ChangeConnect($host, $user, $pass, $db);
  37. }
  38. }
  39.  
  40. }
  41.  
  42. class sql {
  43.  
  44. private $table;
  45. private $params;
  46. private $where;
  47. private $columns;
  48. private $result;
  49. private $sql;
  50. private $order;
  51. private $orderMode = 'ASC';
  52. private $limit;
  53.  
  54. function __construct() {
  55. DBConnect::setConnect();
  56. $this->resetSql();
  57. }
  58.  
  59. public function resetSql() {
  60. $this->table = '';
  61. $this->params = array();
  62. $this->where = array();
  63. $this->result = array();
  64. $this->columns = array();
  65. $this->order = array();
  66. $this->sql = '';
  67. $this->limit = '';
  68. }
  69.  
  70. public function setTable($table) {
  71. $this->table = $table;
  72. }
  73.  
  74. public function setSqlString($string) {
  75. $this->sql = $string;
  76. }
  77.  
  78. public function crearteSQL($mode) {
  79. if ($mode == 'insert') {
  80. $this->sql = 'INSERT INTO ' . $this->table . ' SET ' . implode(', ', $this->params);
  81. }
  82. if ($mode == 'update') {
  83. $this->sql = 'UPDATE ' . $this->table . ' SET ' . implode(', ', $this->params) . ' WHERE ' . implode(' ', $this->where);
  84. }
  85. if ($mode == 'delete') {
  86. $this->sql = 'DELETE FROM ' . $this->table . ' WHERE ' . implode(' ', $this->where);
  87. }
  88. if ($mode == 'select') {
  89. $this->sql = 'SELECT ' . implode(', ', $this->columns) . ' FROM ' . $this->table;
  90. if (!empty($this->where))
  91. $this->sql .= ' WHERE ' . implode(' ', $this->where);
  92. if (!empty($this->order)) {
  93. $this->sql .= ' ORDER BY ' . implode(', ', $this->order) . ' ' . $this->orderMode;
  94. }
  95. if ($this->limit) {
  96. $this->sql .= ' LIMIT ' . $this->limit;
  97. }
  98. }
  99. }
  100.  
  101. public function setLimit($value) {
  102. $this->limit = $value;
  103. }
  104.  
  105. public function setOrderMode($value) {
  106. $this->orderMode = $value;
  107. }
  108.  
  109. public function addOrder($column) {
  110. $this->order[] = $column;
  111. }
  112.  
  113. public function addParam($name, $value, $filter) {
  114. if ($value) {
  115. switch ($filter) {
  116. case 'int':
  117. $value = $this->filterInt($value);
  118. break;
  119. case 'double':
  120. $value = $this->filterDouble($value);
  121. break;
  122. case 'text':
  123. $value = $this->filterText($value);
  124. break;
  125. case 'like':
  126. $value = $this->filterLike($value);
  127. break;
  128. }
  129. } else {
  130. $value = "NULL";
  131. if ($filter == 'double')
  132. $value = '0';
  133. }
  134. $this->params[] = $name . '=' . $value;
  135. }
  136.  
  137. public function addWhere($column, $value, $filter, $sign = '=') {
  138. if ($value) {
  139. switch ($filter) {
  140. case 'int':
  141. $value = $this->filterInt($value);
  142. break;
  143. case 'double':
  144. $value = $this->filterDouble($value);
  145. break;
  146. case 'text':
  147. $value = $this->filterText($value);
  148. break;
  149. case 'like':
  150. $value = $this->filterLike($value);
  151. $sign = ' LIKE ';
  152. break;
  153. }
  154. } else {
  155. $value = "NULL";
  156. }
  157. $this->where[] = $column . $sign . $value;
  158. }
  159.  
  160. public function addTextWhere($value) {
  161. $this->where[] = $value;
  162. }
  163.  
  164. public function addColumn($value) {
  165. $this->columns[] = $value;
  166. }
  167.  
  168. public function addColumns($val = array()) {
  169. if (!empty($val)) {
  170. foreach ($val as $value) {
  171. $this->addColumn($value);
  172. }
  173. }
  174. }
  175.  
  176. public function sqlQuery() {
  177. $this->result = mysqli_query(DBConnect::$db, $this->sql) or die(mysqli_error());
  178. }
  179.  
  180. public function getResult() {
  181. return $this->result;
  182. }
  183.  
  184. public function getRow() {
  185. return mysqli_fetch_assoc($this->result);
  186. }
  187.  
  188. public function numRows() {
  189. return mysqli_num_rows($this->result);
  190. }
  191.  
  192. public function testSQL() {
  193. echo $this->sql . '<br />';
  194. exit();
  195. }
  196.  
  197. private function filter($value, $type) {
  198. $value = mysqli_real_escape_string(DBConnect::$db, $value);
  199. switch ($type) {
  200. case "text":
  201. $value = ($value != "") ? "'" . $value . "'" : "NULL";
  202. break;
  203. case "int":
  204. $value = ($value != "") ? intval($value) : "NULL";
  205. break;
  206. case "double":
  207. $value = ($value != "") ? "'" . doubleval($value) . "'" : "NULL";
  208. break;
  209. }
  210. return $value;
  211. }
  212.  
  213. public function filterInt($value) {
  214. return $this->filter($value, 'int');
  215. }
  216.  
  217. public function filterText($value) {
  218. return $this->filter($value, 'text');
  219. }
  220.  
  221. public function filterDouble($value) {
  222. $value = str_replace(',', '.', $value);
  223. return $this->filter($value, 'double');
  224. }
  225.  
  226. public function filterLike($value) {
  227. return $this->filter('%' . $value . '%', 'text');
  228. }
  229.  
  230. }
  231.  
  232. //przykładowe wywołanie
  233.  
  234. $sql = new sql();
  235. $sql->setTable('kkk k left join iii i on k.kkk_id = i.id');
  236. $cols = array('k.id', 'k.number', 'k.name', 'k.preson');
  237. $sql->addColumns($cols);
  238. $cols = array('i.id as invid', 'i.number as inumber', 'i.name as iname', 'i.preson as iperson');
  239. $sql->addColumns($cols);
  240. $sql->addWhere('k.id', $_GET['id'], 'int');
  241. $sql->crearteSQL('select');
  242. $sql->sqlQuery();
  243. if ($sql->numRows() == 1) {
  244. $row = $sql->getRow();
  245. }
  246.  
  247.  
  248. //inne wywolanie
  249.  
  250. if (isset($_POST['action'])) {
  251. $sql = new sql();
  252. $sql->setTable('anytable');
  253.  
  254. $sql->addParam('flue_sizing', $_POST['flue_sizing'], 'text');
  255. $sql->addParam('flue_route', $_POST['flue_route'], 'text');
  256. $sql->addParam('based_on_client_info', $_POST['based_on_client_info'], 'text');
  257. $sql->addParam('instalation_time1', $_POST['instalation_time1'], 'text');
  258. $sql->addParam('instalation_time1_combo', $_POST['instalation_time1_combo'], 'text');
  259. $sql->addParam('instalation_time2', $_POST['instalation_time2'], 'text');
  260. $sql->addParam('instalation_time2_combo', $_POST['instalation_time2_combo'], 'text');
  261. $sql->addParam('lead_time', $_POST['lead_time'], 'text');
  262. $sql->addParam('lead_time_combo', $_POST['lead_time_combo'], 'text');
  263.  
  264. $sql->addParam('zone', $_POST['zone'], 'text');
  265. $sql->addParam('terrain_category', $_POST['terrain_category'], 'text');
  266. $sql->addParam('basic_wind_speed', $_POST['basic_wind_speed'], 'text');
  267. $sql->addParam('reliability_level', $_POST['reliability_level'], 'text');
  268.  
  269. $sql->addParam('lorry_length', $_POST['lorry_length'], 'text');
  270. $sql->addParam('crane_radius_of_loading', $_POST['crane_radius_of_loading'], 'text');
  271. $sql->addParam('building_height', $_POST['building_height'], 'text');
  272. $sql->addParam('crane_capacity', $_POST['crane_capacity'], 'text');
  273. $sql->addParam('crane_radius_for_lifting', $_POST['crane_radius_for_lifting'], 'text');
  274.  
  275. $sql->addParam('nr_of_appliances', $_POST['nr_of_appliances'], 'text');
  276.  
  277. if ($_POST['action'] == 'edit') {
  278. $sql->addWhere('id', $_POST['id'], 'int');
  279. $sql->addParam('data_mod', date('Y-m-d'), 'text');
  280. $sql->crearteSQL('update');
  281. //$sql->testSQL();
  282. $sql->sqlQuery();
  283. }
  284. }
  285. ?>
Spawnm
Więcej staticów się nie dało?
Czemu setConnect()? getInstance() skoro to singleton.
I czemu singleton?
Masa private, blokujesz rozwój klasy poprzez dziedziczenie.
kayman
klasa powstała w związku z dużymi formularzami i pewnie dlatego singleton w connect bo zapytania w zasadzie dotyczą jednej bazy, jest ich najwyżej kilka ale kolumn duzo

co do private to cenna uwaga ale na dzień dzisiejszy nie bardzo widzę jej rozwój przez dziedziczenie

założenie było takie żeby ona wykonywała prawidłowe i przefiltrowane zapytanie i na tyle czytelne że w razie modyfikacji formularza/bazy/widoku (lub po prostu własnego błędu) można było szybko zmodyfikować duże zapytanie sql
devbazy
crearteSQL? Powinno być raczej createSQL. Nie słyszałem o słowie "crearte". Może to i szczegół, ale warto to poprawić.
kayman
Cytat(devbazy @ 7.11.2013, 07:28:09 ) *
Nie słyszałem o słowie "crearte".


oczywista literówka, dzięki
nospor
Jako wartosc jakiego pola daj 0 a do bazy pojdzie NULL...

Jesli Tobie klasa pasuje to ok, w zasadzie nie nadaje sie do zadnego uzywania ot tak przez ludzi.
Ograniczona funkcjonalnosc,
definiowane danych polaczenia w samej klasie, o, przepraszam, jest changeConnect
stosowanie die, ktore zabije mi aplikacje nawet jak nie chce tego
brak obslugi zastrzezonych nazwa tabel i kolumn
jak wartosc jest pusta to dla double ustawiasz 0, dla INT NULL. hm.... a co jesli ja chce nawet dla DOUBLE dac NULL a nie 0? No i czemu double jest wyroznione a int nie?
$sql->setTable('kkk k left join iii i on k.kkk_id = i.id'); - no nie, tabela to tabela, a LEFT JOIN to LEFT JOIN, nie mieszaj tego
kayman
dzięki za sugestie, jeżeli chodzi o ograniczoną funkcjonalność to racja ale nie wiem czy kiedykolwiek da się stworzyć taką co przewidzi wszystkie opcje, dlatego porobiłem furtki typu setSqlString($string) lub addTextWhere($value)

wartośc 0 zamiast NULL dla double jest mi potrzebna do obecnej aplikacji i przeoczyłem to przy kopiowaniu kodu, oczywiście można wywalić tego ifa smile.gif

b4rt3kk
Cytat(kayman @ 7.11.2013, 12:55:16 ) *
dzięki za sugestie, jeżeli chodzi o ograniczoną funkcjonalność to racja ale nie wiem czy kiedykolwiek da się stworzyć taką co przewidzi wszystkie opcje, dlatego porobiłem furtki typu setSqlString($string) lub addTextWhere($value)

wartośc 0 zamiast NULL dla double jest mi potrzebna do obecnej aplikacji i przeoczyłem to przy kopiowaniu kodu, oczywiście można wywalić tego ifa smile.gif


Da się, spójrz chociażby na ZEND-a.
!*!
Cytat
btw. PDO do mnie nie przemawia jakoś a może przyzwyczaiłem się do starego

Nigdy nie zrozumiem po co ludzie tworzą takie potwory które robią nakładki, skoro jest PDO jako standard. Tylko po to, aby korzystać z metody "crearteSQL" która niewiele mówi i nie klepać ciągle SELECT/UPDATE itd? Absurd.

ps. ciekaw jestem jak skorzystasz z tej klasy na PHP 5.5 w której niema mysql_*

edycja:
źle przeczytałem mysqli_real_escape_string ... zdawało mi się, że mysqli ma być obiektowe...
Spawnm
Ale on ma mysqli_ a nie mysql_ wink.gif
com
!*!

mysqli_* jest zarówno obiektowe jak i strukturalne(pewnie dla tych baranów co nie potrafia obiektowości i zakończyli swoja edukacje na mysql, a teraz bd musieli pozmieniac na i przed biggrin.gif)

Ta klasa ma sesns jeśli podpinamy rózne silniki bazodanowe, ale wtedy jest źle napisana bo ogranicza nas do jednego... Wiesz jak masz 50000 razy napisać SELECT... no to lepiej raz biggrin.gif
!*!
Cytat(com @ 11.11.2013, 00:29:03 ) *
mysqli_* jest zarówno obiektowe jak i strukturalne(pewnie dla tych baranów co nie potrafia obiektowości i zakończyli swoja edukacje na mysql, a teraz bd musieli pozmieniac na i przed biggrin.gif)

O wersji strukturalnej nie wiedziałem... To już w ogóle jest głupotą.

Cytat(com @ 11.11.2013, 00:29:03 ) *
Ta klasa ma sesns jeśli podpinamy rózne silniki bazodanowe, ale wtedy jest źle napisana bo ogranicza nas do jednego... Wiesz jak masz 50000 razy napisać SELECT... no to lepiej raz biggrin.gif

1. "SELECT/UPDATE/INSERT" nie zmieniają się, są stałe, więc co za różnica czy będę je miał w kodzie, a modyfikacja zapytania i tak będzie wymagała interwencji w ten ciąg.

2. Czym podpinanie w klasach podobnych jak powyższa, różni się od tego z PDO?
Już nie mówiąc o tym, że w większych aplikacjach i tak nie stosuje się takich nadbudówek, bo o wiele wydajniej jest napisać na krótko zapytanie, niż zaprzęgać do tego kombajn, często wadliwy.

Rozumiem klasy które mają za zadanie łączenie się z SQL np. pobierając z cfg login i hasło z portem, ale takie coś? Bleee, ohyda.

ps. takie coś, ma niby mi zaoszczędzić czasu?

  1. $sql->addWhere('k.id', $_GET['id'], 'int');
  2. $sql->crearteSQL('select');


To mi przypomniało bzdurą historię sprzed kilku dni... empty() nie jest funkcją! I świat się zmienił...
com
!*! ok masz rację, przyznaje się rzuciłem tylko pobierznie na to okiem, faktycznie ta klasa nie ma sesnsu..

Cytat
O wersji strukturalnej nie wiedziałem... To już w ogóle jest głupotą.

Widze ktoś dawno nie zagladał do manuala http://www.php.net/manual/en/mysqli.construct.php ,ale pewnie pracujesz na PDO biggrin.gif Sam też twierdze, że jest bez sensu no ale jakoś musieli to pogodzić biggrin.gif

Cytat
1. "SELECT/UPDATE/INSERT" nie zmieniają się, są stałe, więc co za różnica czy będę je miał w kodzie, a modyfikacja zapytania i tak będzie wymagała interwencji w ten ciąg.

Właśnie o to chodzi, że się nie zmieniają i to miałem na myśli, na ale faktycznie to co naskrobał za bardzo przypomina PDO i tym samym traci sens wink.gif

Cytat
To mi przypomniało bzdurą historię sprzed kilku dni... empty() nie jest funkcją!

No wiesz niektórym wydaje sie, że wiedzą lepiej od nas haha.gif Jak już o tym mowa to ja usłyszałem, że isset albo empty to nie są metody podrecznikowe tylko pratyczne, albo widziałem kogoś kto sie obudził bo mu register globals przestało działać biggrin.gif Są programiści i programiści wink.gif

widmo_91
Pozwolę się wtrącić.
Bo jakoś dziwnym trafem każdy kto dodaje tu prace od razu dostaje fale krytyki a przecież nie każdy jest PRO i od czegoś trzeba zacząć.
Uważam, że takie klasy jak ta są bardzo ważne i potrzebne, ponieważ pomagają autorowi i klientom klasy ogarnąć podstawy obiektowości i podstawowe polecenia sqla.
Cytat(!*! @ 11.11.2013, 09:28:13 ) *
O wersji strukturalnej nie wiedziałem... To już w ogóle jest głupotą.

Zgadzam się.
Cytat(!*! @ 11.11.2013, 09:28:13 ) *
1. "SELECT/UPDATE/INSERT" nie zmieniają się, są stałe, więc co za różnica czy będę je miał w kodzie, a modyfikacja zapytania i tak będzie wymagała interwencji w ten ciąg.

a hermatyzacja, polimorfizm i pierwszeństwo interfejsów nad implementacją?
Cytat(!*! @ 11.11.2013, 09:28:13 ) *
2. Czym podpinanie w klasach podobnych jak powyższa, różni się od tego z PDO?

Fasadą, możemy bez zmian w kodzie zmieniać implementację klasy na: inne silniki, PDO, pliki, nierelacyjne bazy danych.
Cytat(!*! @ 11.11.2013, 09:28:13 ) *
Już nie mówiąc o tym, że w większych aplikacjach i tak nie stosuje się takich nadbudówek, bo o wiele wydajniej jest napisać na krótko zapytanie

Oczywiście, jednak nie wyobrażam sobie przepuszczania zapytań bezpośrednio przez klasy systemowe nawet przez PDO.
Cytat(!*! @ 11.11.2013, 09:28:13 ) *
niż zaprzęgać do tego kombajn, często wadliwy.

Czy ta klasa to kombajn?
Cytat(!*! @ 11.11.2013, 09:28:13 ) *
ps. takie coś, ma niby mi zaoszczędzić czasu?

  1. $sql->addWhere('k.id', $_GET['id'], 'int');
  2. $sql->crearteSQL('select');

Czy więcej kodu oznacza więcej straconego czasu? Czy w programowaniu obiektowym chodzi zawsze o mniejszą liczbę kodu(np metody typu: get, set)? Czy może o czytelność i łatwość rozbudowy?

Cytat(com @ 11.11.2013, 16:39:02 ) *
No wiesz niektórym wydaje sie, że wiedzą lepiej od nas haha.gif

To kim wy jesteście, że wiecie wszystko najlepiej?
W takim razie sprzedaję 28 tomów encyklopedii jak wy wszystko wiecie najlepiej.
!*!
Cytat
a hermatyzacja, polimorfizm i pierwszeństwo interfejsów nad implementacją?

To nie ta bajka.

Cytat
Fasadą, możemy bez zmian w kodzie zmieniać implementację klasy na: inne silniki, PDO, pliki, nierelacyjne bazy danych.

Jak coś jest do wszystkiego, to jest do niczego. Z tego co pamiętam w OOP właśnie chodzi o rozbicie wszystkiego co możliwe, a nie budowę jednego kombajnu który ma w sobie wszytko.
W powyższej klasie nie ma rozbicia na inne silniki, odróżnienie bazy od SQL / pliki. Jest tylko nadbudówka która nie jest przydatna, ponieważ wszytko to jest dostępne natywnie z poziomu PDO.

Cytat
Czy więcej kodu oznacza więcej straconego czasu? Czy w programowaniu obiektowym chodzi zawsze o mniejszą liczbę kodu(np metody typu: get, set)? Czy może o czytelność i łatwość rozbudowy?

Czytaj wyżej. Nie chodzi o ilość kodu do napisania, tylko o elastyczność której tu brakuje. Nie ma sensu pisać

  1. $sql->addWhere('k.id', $_GET['id'], 'int');
  2. $sql->crearteSQL('select');


skoro jest
  1. $stmt = $pdo -> prepare('SELECT ...


A że nie muszę pisać polecenia SQL w całości z palca? Co z tego skoro muszę i tak zrobić odwołanie do metody.
Dlatego spór o to czy pisać główną konstrukcje czy nie, był dobry tak samo jak klasy które tworzyły jeden interfejs, dawno temu, przed PDO.
com
Cytat
Uważam, że takie klasy jak ta są bardzo ważne i potrzebne, ponieważ pomagają autorowi i klientom klasy ogarnąć podstawy obiektowości i podstawowe polecenia sqla.

Sam sobie przeczysz.. bo jak ktoś skorzysta z takiej "klasy" nie majac duzego pojecia itak nie pozna np sql bo wszystko ma opakowane i wywołuje to np jak tu
  1. $sql->addWhere('k.id', $_GET['id'], 'int');
  2. $sql->crearteSQL('select');

co mu tak naprawde nic nie mówi... Ja w pierwszej swojej wypowiedzi przeoczyłem to, na co zwrócił mi uwage !*! i miał rację, ponadto wymyślanie koła na nowo tylko dla satysfakcji, że działa jest bez sensu, w tym przypadku ponieważ tak jak powiedziano ta klasa nie ma niczego wiecej niż dostarcza nam PDO, a nawet dało by się wymienić szereg ograniczen, chociażby wspomniane przez mnie czy prez Ciebie inne silniki bazodanowe...

Cytat
To kim wy jesteście, że wiecie wszystko najlepiej?

Nikt nie wie wszystkiego tym bardziej najlepiej, źle zinterpretowałeś te słowa, chodziło o to że przychodzą tu osoby, które nie posiadają wiedzy, bo sie jescze uczą i próbują nam wmawiać, że cos nie działa albo działa zupełnie inaczej niż ma, a sami nawet czesto nie zajrzeli do manuala, tylko mówią bo im sie tak wydaje... i potem potrafia prowadzic dyskusje na jakis temat która itak kończy sie na tym że sie okazuje iż mieliśmy rację... Nie twierdze że nik nie ma prawa do pomyłek, ale jesli jest sie czegoś pewnym to trzeba miec na to niezbite dowody...

Najlepiej zakończmy te dyskusję bo powoli odbiega ona od tematu oceny..

Jedno jest pewne !*! masz napewno rację smile.gif

Cytat
Wiesz jak masz 50000 razy napisać SELECT... no to lepiej raz


Tutaj faktycznie to jest tak jak powiedziałeś, choć można by zaimplementować to troche inaczej z zachowaniem elastyczności i troche w kierunku tego co powiedziałem, ale to już nie w tym temacie, dlatego Twoje argumenty są jak nabardziej słuszne jesli chodzi o klase zaprezetowaną w tym wątku i też sie z Tobą zgadzam smile.gif
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.