Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MYSQL][PHP] Wysyłanie zapytania do mysql
Forum PHP.pl > Forum > Przedszkole
Koldy
Siemanko mam takie pytanie: Czy to jest poprawne? w sensie takim czy tak się używa.
  1. $ile = mysql_num_rows(mysql_query("SELECT cid FROM comments WHERE post='$jid'"));


Jak najlepiej robić zapytania i je wysyłać, bo jak tak sobie robie:
  1. $q = "SELECT * FROM comments, users WHERE comments.user = users.uid AND post='$jid' ORDER BY cid DESC";
  2. $qid = mysql_query($q);
  3. $ile = mysql_num_rows($qid);

to się trochę syf robi, jak dbacie o to by wasz kod był przejżysty przy powtarzających się rzeczach?
podzielcie się smile.gif
CuteOne
1. Jeżeli pobierasz dane tylko po to aby zliczyć wiersze to używaj COUNT() zamiast mysql_num_rows()
2.
  1. $query = mysql_query("SELECT * FROM comments, users WHERE comments.user = users.uid AND post='$jid' ORDER BY cid DESC");
  2. $ile = mysql_num_rows($qid);

3. Tego typu rzeczy robi się za pomocą funkcji aby jak to już sam zauważyłeś nie brudzić kodu.
  1. $select = $db -> fetchRow("SELECT *, COUNT(*) as count FROM comments, users WHERE comments.user = users.uid AND post='$jid' ORDER BY cid DESC");
  2. echo $select['count'];


A w ogóle było by cudownie gdybyś przerzucił się na PDO.
Sephirus
Ad. 2

Dla bardziej skomplikowanych (tak naprawdę po prostu dłuższych) zapytań osobiście polecam wyrzucenie zapytania poza ciało funkcji tak jak zaproponował autor:

  1. $query = "SELECT a.costam1, a.costam2, a.costam3 FROM tabelka1 AS a " .
  2. "LEFT JOIN tabelka2 AS b ON a.id1 = b.id2 " .
  3. "WHERE a.jakies_pole LIKE 'to jest jakis tekst%' " .
  4. "ORDER BY a.jakies_pole ASC LIMIT 0,100";
  5.  
  6. $query = mysql_query($query);
  7.  
  8. // dalsze instrukcje


Dla dłuższych zapytań niezależnie od tego czy uzywa się funkcji z rodziny mysql_* czy PDO czy czegokolwiek innego (może poza ORM) to dobry zwyczaj bo kod staje się o wiele czytelniejszy a poprawne podzielenie zapytania na linie może jedynie pomóc w jego zrozumieniu przez osoby trzecie, które kiedyś mogą na dany kod zerknąć...

I teraz odnosząc się do tego co napisał mój przedmówca - weź sobie do serca tą radę z PDO Autorze - to raz a dwa:

mysql_num_rows() jak i jego odpowiednik w PDO czyli pdostatement::rowCount() służą owszem do pobrania liczby rekordów i można z nich korzystać ale tylko gdy pobierasz rekordy w celu ich wyświetlenia (wszystkich) a dodatkowo potrzebujesz znać ich liczbę... Tak jak napisał przedmówca jeśli potrzebujesz z bazy jedynie liczby rekordów spełniającej dane kryteria bardzo mile widziane jest COUNT()

wink.gif
Koldy
Wziąć, wziąłem sobie do serca, bo od rana siedzę przy PDO, tyle że już jestem w pierwszym rowie..
mianowicie wcześniej mogłem wysyłać zapytania "globalnie", teraz nie widzę PDO w innych funkcjach, szukałem coś i znalazłem singleton, ale dużo osób to krytykuje..

więc jak? w każdej funkcji mam tworzyć nowe PDO?

  1. $dbh = new PDO('mysql:host=localhost;dbname='.DB_NAME, DB_USER, DB_PASSWORD);

like that?
Sephirus
Hmm kto krytykuje singleton?? O_o

Zrób singleton - zwracający obiekt PDO już połączony i po krzyku... Nie wiem w czym problem

  1. class MyPDO
  2. {
  3. private static $instance = null;
  4.  
  5. public static getInstance()
  6. {
  7. if(!(self::$instance instanceOf MyPDO)) self::$instance = new PDO('mysql:host=localhost;dbname='.DB_NAME, DB_USER, DB_PASSWORD);
  8. return self::$instance;
  9. }
  10.  
  11. private __construct() {}
  12. }


I tam gdzie potrzebujesz dajesz np:

  1. $db = MyPDO::getInstance();
  2.  
  3. $st = $db->prepare('SELECT * FROM users WHERE id = ?');
  4. $st->execute(array(123));
  5. $user= $st->fetchObject();
  6.  
  7. // itd... gdzie tylko potrzebujesz bazy...
Koldy
Czytałem kilka opini gdzie narzekali na Singleton, że się nie da na kilku bazach pracować itp.

Pewnie teraz mnie rozniesiecie, ale:
  1. class MyPDO
  2. {
  3. private static $instance = null;
  4.  
  5. public static getInstance()
  6. {
  7. if(!(self::$instance instanceOf MyPDO)) self::$instance = new PDO('mysql:host=localhost;dbname='.DB_NAME, DB_USER, DB_PASSWORD);
  8. return self::$instance;
  9. }
  10.  
  11. private __construct() {}
  12. }

Czy zamiast tego mógłbym zrobić:
  1. function db() {
  2. try {
  3. $dbh = new PDO('mysql:host=localhost;dbname='.DB_NAME, DB_USER, DB_PASSWORD);
  4. } catch (PDOException $e) {
  5. print "Error!: " . $e->getMessage() . "<br/>";
  6. die();
  7. }
  8. return $dbh;
  9. }

i to nie było by to samo?
phpion
Cytat(Koldy @ 31.01.2012, 11:45:21 ) *
Czytałem kilka opini gdzie narzekali na Singleton, że się nie da na kilku bazach pracować itp.

E tam dupa. Moim zdaniem singleton jest czasem dobrym wyjściem, a co do połączenia singletona i kilku baz danych to Kohana 2 obsługuje właśnie taki mechanizm, więc jak widać da się.
Sephirus
Nikt Cię nie rozniesie smile.gif

Ale oczywiście to jest zły pomysł w dokładnie takiej formie... dlaczego? Bo każdorazowo łączy się z bazą...

Singleton jest powszechnie używany i sprawdzony smile.gif

Co prawda można przerobić tą funkcję tak by to miało sens - ale nie ma co odkładać na bok sprawdzonych wzorców ;/

A dla tych co mają problem z obsługą wielu różnych połączeń do bazy i singletonem - mam dwa słowa - "fabryka singletonów" tongue.gif - dziękuję smile.gif

Zresztą wydaje mi się że każdy prosty DBAL jest zbudowany wstępnie w oparciu o singleton smile.gif

Przykład pseudo fabryki singletonów do obsługi bazy danych:

  1. class Db
  2. {
  3. public static $connections = array();
  4. private static $instances = array();
  5.  
  6. public static getInstance($connectionName = 'default')
  7. {
  8. $data = self::$connections[$connectionName];
  9.  
  10. if(!isset(self::$instances[$connectionName]))
  11. self::$instances[$connectionName] = new PDO('mysql:host='.$data->host.';dbname='.$data->dbname, $data->user, $data->password);
  12. return self::$instances[$connectionName];
  13. }
  14.  
  15. public function addConnection($host,$user,$password,$dbname,$connectionName = 'default')
  16. {
  17. self::$connections[$connectionName] = new stdClass;
  18. self::$connections[$connectionName]->host = $host;
  19. self::$connections[$connectionName]->user = $user;
  20. self::$connections[$connectionName]->password = $password;
  21. self::$connections[$connectionName]->dbname = $dbname;
  22. }
  23. }
  24.  
  25. // przykład użycia:
  26.  
  27. // ustalamy dane do domyślnego połączenia:
  28. Db::addConnection('localhost','user','pass','tabelka');
  29. // i do drugiego:
  30. Db::addConnection('123.123.123.123','user2','pass2','tabelkaX','drugie');
  31.  
  32.  
  33. $db = Db::getInstance(); // pobieramy domyślne połączenie
  34.  
  35. // potem gdzie indziej możemy się do drugiego odwołać poprzez:
  36. $db = Db::getInstance('drugie');
  37.  
  38. // itd...
  39.  


EDIT: oczywiście przedstawiłem sam koncept bez obsługi wyjątków i sprawdzania błędów smile.gif
CuteOne
Sephirus: nie zgodzę się z Tobą w kwestii wstępnego zapisu zapytania do zmiennej. Jaki to ma sens?
  1. $query = "SELECT a.costam1, a.costam2, a.costam3 FROM tabelka1 AS a " .
  2. "LEFT JOIN tabelka2 AS b ON a.id1 = b.id2 " .
  3. "WHERE a.jakies_pole LIKE 'to jest jakis tekst%' " .
  4. "ORDER BY a.jakies_pole ASC LIMIT 0,100";
  5. $select = mysql_query($query);
  6.  
  7. $select = mysql_query("SELECT a.costam1, a.costam2, a.costam3
  8. FROM tabelka1 AS a
  9. LEFT JOIN tabelka2 AS b ON a.id1 = b.id2
  10. WHERE a.jakies_pole LIKE 'to jest jakis tekst%'
  11. ORDER BY a.jakies_pole ASC LIMIT 0,100");

?

Koldy: zastanów się czym jest singleton i kiedy się go wykorzystuje a dojdziesz do prostego wniosku, że jest idealny do obsługi bazy danych smile.gif


ps. również Zend wykorzystuje singleton do obsługi bazy danych wink.gif
nospor
Cytat
: nie zgodzę się z Tobą w kwestii wstępnego zapisu zapytania do zmiennej. Jaki to ma sens?
Ano choćby taki, że możesz zrobic echo $query; i sobie sprawdzić co masz nie tak w zapytaniu gdy pluje ci błędem.
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.