Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [MYSQL][PHP] Wysyłanie zapytania do mysql
Koldy
post
Post #1





Grupa: Zarejestrowani
Postów: 98
Pomógł: 1
Dołączył: 28.06.2009
Skąd: Great Britan

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


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


--------------------
$progress++;
Go to the top of the page
+Quote Post
CuteOne
post
Post #2





Grupa: Zarejestrowani
Postów: 2 958
Pomógł: 574
Dołączył: 23.09.2008
Skąd: wiesz, że tu jestem?

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


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.

Ten post edytował CuteOne 31.01.2012, 05:25:31
Go to the top of the page
+Quote Post
Sephirus
post
Post #3





Grupa: Zarejestrowani
Postów: 1 527
Pomógł: 438
Dołączył: 28.06.2011
Skąd: Warszawa

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


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

Ten post edytował Sephirus 31.01.2012, 08:52:24


--------------------
If you're good at something, never do it for free.
Potrzebujesz skryptu JS lub PHP - szukasz kogoś kto przetestuje twoją aplikację pod względem bezpieczeństwa? Szybko i solidnie? Napisz ;)
Mój blog - Jak zwiększyć wydajność front-endu - O buforowaniu wyjścia w PHP słów kilka...
Go to the top of the page
+Quote Post
Koldy
post
Post #4





Grupa: Zarejestrowani
Postów: 98
Pomógł: 1
Dołączył: 28.06.2009
Skąd: Great Britan

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


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?

Ten post edytował Koldy 31.01.2012, 11:25:59


--------------------
$progress++;
Go to the top of the page
+Quote Post
Sephirus
post
Post #5





Grupa: Zarejestrowani
Postów: 1 527
Pomógł: 438
Dołączył: 28.06.2011
Skąd: Warszawa

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


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...


Ten post edytował Sephirus 31.01.2012, 11:38:57


--------------------
If you're good at something, never do it for free.
Potrzebujesz skryptu JS lub PHP - szukasz kogoś kto przetestuje twoją aplikację pod względem bezpieczeństwa? Szybko i solidnie? Napisz ;)
Mój blog - Jak zwiększyć wydajność front-endu - O buforowaniu wyjścia w PHP słów kilka...
Go to the top of the page
+Quote Post
Koldy
post
Post #6





Grupa: Zarejestrowani
Postów: 98
Pomógł: 1
Dołączył: 28.06.2009
Skąd: Great Britan

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


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?


--------------------
$progress++;
Go to the top of the page
+Quote Post
phpion
post
Post #7





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




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





Grupa: Zarejestrowani
Postów: 1 527
Pomógł: 438
Dołączył: 28.06.2011
Skąd: Warszawa

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


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

Ten post edytował Sephirus 31.01.2012, 12:33:22


--------------------
If you're good at something, never do it for free.
Potrzebujesz skryptu JS lub PHP - szukasz kogoś kto przetestuje twoją aplikację pod względem bezpieczeństwa? Szybko i solidnie? Napisz ;)
Mój blog - Jak zwiększyć wydajność front-endu - O buforowaniu wyjścia w PHP słów kilka...
Go to the top of the page
+Quote Post
CuteOne
post
Post #9





Grupa: Zarejestrowani
Postów: 2 958
Pomógł: 574
Dołączył: 23.09.2008
Skąd: wiesz, że tu jestem?

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


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





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




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.


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

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: 22.08.2025 - 07:44