ďťż

[PHP] klasa obsługująca MySQL prośba o krytykę ;)

       

Podstrony


telcocafe

Witam, napisałem wstępnie o to taką klasę która ma się łączyć ze SQL:
final class SQL { private $host = 'localhost'; private $user = 'root'; private $password = 'root'; private $database = 'name'; private $charset = 'UTF8'; private $link; public function __construct() { $this->link = @mysql_connect($this->host,$this->user,$this->password); @mysql_select_db($this->database); @mysql_set_charset($this->charset); //@mysql_query('SET NAMES '.$this->charset); // dla wczesniejszej wersji php } public function __destruct() { mysql_close($this->link); } public function select($table,$conditions=NULL,$order=NULL,$limit=NULL) { if(!is_null($conditions)) $conditions = 'WHERE '.$conditions; if(!is_null($order)) $order = 'ORDER BY '.$order; if(!is_null($limit)) $limit = 'LIMIT '.$limit; return mysql_query("SELECT * FROM $table $conditions $order $limit"); } public function add($table,$colls,$values) { mysql_query("INSERT INTO $table ($colls) VALUES ($values);"); } public function delete($table,$conditions=NULL,$limit=NULL) { if(!is_null($conditions)) $conditions = 'WHERE '.$conditions; if(!is_null($limit)) $limit = 'LIMIT '.$limit; mysql_query("DELETE FROM $table $conditions $limit"); } public function rowsAmount($table,$conditions=NULL,$order=NULL,$limit=NULL) { return mysql_num_rows($this->select($table)); } }
Chciałbym prosić Was o krytykę. Co źle, co wbrew semantyce, co można by zrobić korzystniej a co niepotrzebne. Jest to zaledwie zalążek, ale jak widzicie, mam zamiar ją rozbudować o kolejne metody. Btw, czy w destruktorze może zawierać się zamknięcie połączenia z SQL?
Użytkownik Isaac from Vale edytował ten post 03 czerwiec 2010, 13:47


Korzystasz ze starej biblioteki mysql_*, która nie obsługuje nawet podpinania danych do zapytań, transakcji i wielu innych przydatnych możliwości bazy MySQL. Jeżeli zależy Ci na tej funkcjonalności, zastosuj MySQLi.

Ogólnie w PHP jest bałagan w bibliotekach, ale coś trzeba wybrać [mysql, mysqli, PDO]

Klasa jest w porządku, ale mam zastrzeżenia

1. select() ogranicza budowanie zapytań typu SELECT do 1 tabeli i słów: WHERE, ORDER BY, LIMIT
2. add() opiera się na zwykłym przekazywaniu danych do zapytania

Być może select() wystarczy do większości zapytań. Co do add() - poczytaj o podpinaniu danych i wypróbuj, jak to działa. Jeżeli dodajesz kilka rekordów na raz, nawet zyskasz na wydajności. Pamiętaj jednak o objęciu operacji INSERT, UPDATE i DELETE transakcją, aby zachować spójność danych (jak wystąpi błąd w 1 zapytaniu, inne zostaną anulowane).

Używasz cudzysłowów zamiast apostrofów. Lepiej wyglądają te drugie.
W destrukcji klasy brakuje sprawdzenia, czy do połączenia w ogóle doszło. Z wykorzystaniem strukturalnego MySQLi to by wyglądało tak:class DB { private $_connection; public function __construct() { $this->_connection = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME); if (!$this->_connection) throw new Exception('Błąd połączenia z bazą danych. Kod błędu: '.mysqli_connect_errno()); mysqli_set_charset($this->_connection, 'utf8'); } public function __destruct() { if ($this->_connection) mysqli_close($this->_connection); } }
Co do metody dodającej wpis, to można zrobić to w prostszy sposób:class DB { function insert($table, $data, $type = 'insert') { $keys = array(); $values = array(); foreach ($data as $key => &$value) { $keys[] = $key; $values[] = var_export($value, 1); } $this->query($type.' into `'.$table.'` (`'.implode('`, `', $keys).'`) values ('.implode(', ', $values).')'); } }Masz tutaj uproszczone zadanie, bo nie musisz robić dwóch ciągów i masz zapewnioną odporność na SQL Injection nawet jeśli byś o tym zapomniał. Wtedy przykładowo dodajesz dane:$db->insert('uzytkownicy', array( 'id' => null, 'nazwa' => $_POST['nazwa'], 'haslo' => md5($_POST['haslo']), 'wiek' => (int)$_POST['wiek'], 'aktywny' => 0 ));
Brakuje też metody aktualizującej, która wyglądałaby podobnie do przedstawionej przeze mnie metody dodającej (można nawet pokusić się o uproszczenie kodu tych dwóch metod):class DB { function update($table, $data1, $data2) { foreach ($data1 as $key => &$value) $data1[$key] = '`'.$key.'`='.var_export($value, 1); foreach ($data2 as $key => &$value) $data2[$key] = '`'.$key.'`='.var_export($value, 1); return $this->query('update `'.$table.'` set '.implode(', ', $data1).' where '.implode(' and ', $data2)); } }

andrzej_aa dlaczego jest tam zmienna $type np przy metodzie dodawanie rekordu do tabeli? Co może tam być prócz insert? Co do mysqli dobrym rozwiązaniem byłoby rozszerzenie tej klasy o moją klasę SQL?



Twoja klasa jest prostą nakładką i da się w niej wykorzystać MySQLi, czy PDO lub inne API.

Poza insert jest jeszcze replace. Przerobiłem przykład na taki:class DB { function insert($table, $data, $type = 'insert', $where = false) { $array = array(); foreach ($data as $key => &$value) $array[] = '`'.$key.'`='.var_export($value, 1); if ($where) { foreach ($where as $key => &$value) $where[$key] = '`'.$key.'`='.var_export($value, 1); $this->query($type.' `'.$table.'` set '.implode(', ', $array).' where '.implode(' and ', $where)); } else $this->query($type.' into `'.$table.'` set '.implode(', ', $array)); } function replace($table, $data) { $this->insert($table, $data, 'replace'); } function update($table, $data, $where) { $this->insert($table, $data, 'update', $where); } }
Użytkownik andrzej_aa edytował ten post 03 czerwiec 2010, 22:53
Zdecydowałem się przejść z mysql na PDO, gdyż to drugie umożliwia największą uniwersalność. A co do selecta, jak powinienem rozbudować tą metodę, co wziąć pod uwagę, aby też było jak najbardziej uniwersalne pod kątem złożonych zapytań? :)

  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • nvm.keep.pl

  • Sitedesign by AltusUmbrae.