Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

2 Stron V   1 2 >  
Reply to this topicStart new topic
> PDO i zamykanie połączenia ?
Mayka
post 9.12.2013, 22:43:11
Post #1





Grupa: Zarejestrowani
Postów: 304
Pomógł: 1
Dołączył: 12.01.2009
Skąd: Kanapa

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


Witam, chciałem zapytać czy jest jakieś polecenie/wywołanie do zamknięcia połączenia przy PDO i mysql ?
  1. function dbInit(){
  2. $dbs=new PDO('mysql:host='.$DBVARS['hostname'].';port='.$DBVARS['port'].';dbname='.$DBVARS['db_name'],$DBVARS['username'],$DBVARS['password']);
  3. $dbs->query('SET NAMES utf8');
  4. $dbs->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  5. $dbs->num_queries=0;
  6. $GLOBALS['db']=$dbs;
  7. return $dbs;
  8. }
  9. function dbQuery($query){
  10. $dbs=dbInit();
  11. $q=$dbs->query($query);
  12. $dbs->num_queries++;
  13. return $q;
  14. }
  15. function dbRows($query) {
  16. $q = dbQuery($query);
  17. //print_r($dbs->errorInfo());
  18. return $q->fetchAll(PDO::FETCH_ASSOC);
  19. }


Znalazłem takie coś w skryptach/książkach, i bardzo ciekawie się to sprawdza tylko że niestety niewiem czemu generuje to 25tyś połączeń przy 20użytkownikach.. Czy ktoś jest mi wstanie pomóc/ przerobić to tak żeby nie było połączenia/inicjacji bazy przy każdym dbQuery() ? Ew czy to można jakoś zamknąć ?
Go to the top of the page
+Quote Post
Turson
post 9.12.2013, 22:45:30
Post #2





Grupa: Zarejestrowani
Postów: 4 291
Pomógł: 829
Dołączył: 14.02.2009
Skąd: łódź

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


http://www.php.net/manual/en/pdostatement.closecursor.php
Go to the top of the page
+Quote Post
Mayka
post 9.12.2013, 23:41:08
Post #3





Grupa: Zarejestrowani
Postów: 304
Pomógł: 1
Dołączył: 12.01.2009
Skąd: Kanapa

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


tzn mam dołożyć $dbs->closeCursor(); ?
Go to the top of the page
+Quote Post
Methestel
post 10.12.2013, 00:30:21
Post #4





Grupa: Zarejestrowani
Postów: 46
Pomógł: 10
Dołączył: 30.06.2008

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


Radzę w ogóle zmienić podejście i ten antypattern zamienic na coś rozsądniejszego np:

  1. <?php
  2. class PdoFactory {
  3. private static $pdoInstances = array();
  4.  
  5. private function __construct() {}
  6.  
  7. /**
  8. * @param string $key
  9. * @throws PDOException
  10. * @throws Exception
  11. */
  12. private static function set($key = null) {
  13. try {
  14. //Tutaj wstaw fragment kodu ktory ustawi odpowiednie wartosci dla $dsn, $user, $password
  15.  
  16. $pdo = new PDO($dsn, $user, $password);
  17. $pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
  18. $pdo->setAttribute( PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
  19. self::$pdoInstances[$key] = $pdo;
  20. } catch (PDOException $e) {
  21. echo 'Connection failed: '.$e->getMessage();
  22. throw $e;
  23. } catch (Exception $e) {
  24. echo $e->getMessage();
  25. throw $e;
  26. }
  27. }
  28.  
  29. /**
  30. * @param string $key
  31. * @return PDO
  32. */
  33. public static function get($key) {
  34. if (!isset(self::$pdoInstances[$key])) {
  35. self::set($key);
  36. }
  37. return self::$pdoInstances[$key];
  38. }
  39.  
  40. public static function closeAll() {
  41. foreach ( self::$pdoInstances as $key => $pdo ) {
  42. self::$pdoInstances[$key] = null;
  43. }
  44. }
  45. }
  46. ?>


Obiekt klasy PDO pobierasz przez PdoFactory::get('nazwaPolaczenia');
Jeśli korzystasz tylko z jednej bazy danych możesz zmodyfikować skrypt tak żeby nie trzeba było podawać w ogóle parametru do metody PdoFactory::get()
Przed zakończeniem skryptu lub w momencie kiedy jesteś pewien że nie będziesz już potrzebował komunikacji z bazą danych pamiętaj o wywołaniu PdoFactory::closeAll()
Go to the top of the page
+Quote Post
Mayka
post 10.12.2013, 10:09:06
Post #5





Grupa: Zarejestrowani
Postów: 304
Pomógł: 1
Dołączył: 12.01.2009
Skąd: Kanapa

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


A mogłbyś jeszcze powiedzieć jak teraz przez to pobrać dane ?
Go to the top of the page
+Quote Post
!*!
post 10.12.2013, 10:46:15
Post #6





Grupa: Zarejestrowani
Postów: 4 298
Pomógł: 447
Dołączył: 16.11.2006

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


Zamiast tworzyć jakieś bzdurne klasy korzystaj z PDO takim jakie jest. http://pl.wikibooks.org/wiki/PHP/Biblioteka_PDO


--------------------
Nie udzielam pomocy poprzez PW i nie mam GG.
Niektóre języki programowania, na przykład C# są znane z niezwykłej przenośności (kompatybilność ze wszystkimi wersjami Visty jest wiele warta).
Go to the top of the page
+Quote Post
Methestel
post 10.12.2013, 14:47:41
Post #7





Grupa: Zarejestrowani
Postów: 46
Pomógł: 10
Dołączył: 30.06.2008

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


Trzymając się kodu z pierwszego posta i wykorztując klasę PdoFactory którą Ci podałem mogłoby wyglądać to np tak:

  1. function dbQuery($query){
  2. $dbs=PdoFactory::get('identyfikatorPołączenia');
  3. //lub $dbs=PdoFactory::get(); - w zależności czy chcesz obsługiwać kilka połączeń czy tylko jedno
  4. $q=$dbs->query($query);
  5. $dbs->num_queries++;
  6. return $q;
  7. }
  8. function dbRows($query) {
  9. $q = dbQuery($query);
  10. //print_r($dbs->errorInfo());
  11. return $q->fetchAll();
  12. }


Funkcja dbInit() nie jest Ci już potrzebna. Obiekty klasy PDO pobierasz teraz używając klasy PdoFactory. Zaletą tego jest to że PdoFactory::get() nie będzie łączyć się za każdym razem z bazą danych. Zrobi to raz a potem będzie już zwracane wcześniej utworzony obiekt klasy PDO.
Go to the top of the page
+Quote Post
Mayka
post 10.12.2013, 19:28:32
Post #8





Grupa: Zarejestrowani
Postów: 304
Pomógł: 1
Dołączył: 12.01.2009
Skąd: Kanapa

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


Cytat(!*! @ 10.12.2013, 10:46:15 ) *
Zamiast tworzyć jakieś bzdurne klasy korzystaj z PDO takim jakie jest. http://pl.wikibooks.org/wiki/PHP/Biblioteka_PDO


Widziałem tą strone, tylko że $stmt -> closeCursor(); które tutaj jest podane powoduje u mnie błąd Call to undefined method PDO::closeCursor() '


@Methestel
To zwykłe pdo nie potrafi zrobić jednego połączenia ?

Znalazłem coś takiego:
$dbs->db = null;

Czy jak wstawie takie coś do dbquery i dbrows na koniec to połączenie zostanie zamknięte po każdym wczytaniu/zmianie ?

Ten post edytował Mayka 10.12.2013, 19:32:03
Go to the top of the page
+Quote Post
Damonsson
post 10.12.2013, 20:08:00
Post #9





Grupa: Zarejestrowani
Postów: 2 355
Pomógł: 533
Dołączył: 15.01.2010
Skąd: Bydgoszcz

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


Po co Ci to manualne zamykanie połączenia?

Jak już to $dbs = null;

Ten post edytował Damonsson 10.12.2013, 20:10:15
Go to the top of the page
+Quote Post
Methestel
post 10.12.2013, 20:24:07
Post #10





Grupa: Zarejestrowani
Postów: 46
Pomógł: 10
Dołączył: 30.06.2008

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


Zwykłe PDO jak najbardziej potrafi zrobić jedno połączenie. Tylko chodzi o to żeby nie robił tych połączeń przy każdym zapytaniu tylko maksymalnie raz podczas jednego requesta. Nie wiem jak to prościej wyjaśnić ... może wyobraź sobie że masz do wykonania 100 zapytań do bazy danych.
Masz do wyboru:
- przed każdym zapytaniem tworzysz nowe połączenie z bazą danych i wykonujesz zapytanie (łącznie wykonujesz 100 połączeń z bazą danych i 100 zapytań)
- tworzysz jedno połączenie z bazą danych i używając tylko tego jednego połączenia wykonujesz kolejno 100 zapytań (łącznie 1 połączenie z bazą danych i 100 zapytań)

Efekt końcowy będzie taki sam. Jak myślisz, które rozwiązanie jest lepsze?


Tak, jak wstawisz $dbs = null na koniec dbquery to połączenia będą zamykane - zresztą masz to jak wół napisane w dokumentacji http://www.php.net/manual/en/pdo.connections.php
Jeśli nie przeszkadza Ci że przy każdym zapytaniu będziesz od nowa łączył się z bazą danych to nie ma problemu.

Ten post edytował Methestel 10.12.2013, 20:26:32
Go to the top of the page
+Quote Post
ctom
post 10.12.2013, 22:07:55
Post #11





Grupa: Zarejestrowani
Postów: 321
Pomógł: 55
Dołączył: 19.04.2009

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


tak jak napisał @Methestel problemem w Twoim skrypcie nie jest zamykanie połączeń ale ich nadmierne "otwieranie" - a podejrzewam, że Twoim jest to


--------------------
Polecam MyDevil hosting idealny dla deweloperów
Go to the top of the page
+Quote Post
Turson
post 10.12.2013, 22:44:25
Post #12





Grupa: Zarejestrowani
Postów: 4 291
Pomógł: 829
Dołączył: 14.02.2009
Skąd: łódź

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


Jeśli przy każdym zapytaniu nawiązujesz połączenie z bazą przez dbInit() to jest bezsensu. Jak piszesz w OOP to w konstruktorze nawiązujesz połączenie z bazą i później tylko się odwołujesz przez np. $this->db, albo tworzysz instancję new PDO i działasz na tym w całym dokumencie.
Go to the top of the page
+Quote Post
Mayka
post 11.12.2013, 17:12:25
Post #13





Grupa: Zarejestrowani
Postów: 304
Pomógł: 1
Dołączył: 12.01.2009
Skąd: Kanapa

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


Cytat(Turson @ 10.12.2013, 22:44:25 ) *
Jeśli przy każdym zapytaniu nawiązujesz połączenie z bazą przez dbInit() to jest bezsensu. Jak piszesz w OOP to w konstruktorze nawiązujesz połączenie z bazą i później tylko się odwołujesz przez np. $this->db, albo tworzysz instancję new PDO i działasz na tym w całym dokumencie.


A jak nie pisze w oop ?
To jak to zrobić żeby połączenie było raz wykonywane a nie przy każdym requescie ?

Cytat(Methestel @ 10.12.2013, 20:24:07 ) *
Tak, jak wstawisz $dbs = null na koniec dbquery to połączenia będą zamykane - zresztą masz to jak wół napisane w dokumentacji http://www.php.net/manual/en/pdo.connections.php
Jeśli nie przeszkadza Ci że przy każdym zapytaniu będziesz od nowa łączył się z bazą danych to nie ma problemu.


A czemu ma mi to przeszkadzać bo nie rozumiem ?
Go to the top of the page
+Quote Post
ctom
post 11.12.2013, 17:30:54
Post #14





Grupa: Zarejestrowani
Postów: 321
Pomógł: 55
Dołączył: 19.04.2009

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


Cytat(Mayka @ 11.12.2013, 17:12:25 ) *
To jak to zrobić żeby połączenie było raz wykonywane a nie przy każdym requescie ?


przecież @Methestel Ci napisał jak tu

Cytat(Mayka @ 11.12.2013, 17:12:25 ) *
Cytat(Mayka)

Jeśli nie przeszkadza Ci że przy każdym zapytaniu będziesz od nowa łączył się z bazą danych to nie ma problemu.


A czemu ma mi to przeszkadzać bo nie rozumiem ?


może twój serwer będzie miał coś przeciwko ;-) ? pewnie masz apache , to zrób sobie test wydajności twojego rozwiązania i tego z jednym inicjowanym połączeniem (np. ab -n 1000 -c 10 )


--------------------
Polecam MyDevil hosting idealny dla deweloperów
Go to the top of the page
+Quote Post
Methestel
post 11.12.2013, 17:31:54
Post #15





Grupa: Zarejestrowani
Postów: 46
Pomógł: 10
Dołączył: 30.06.2008

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


Sama się pytasz w pierwszym poście jak zrobić "żeby nie było połączenia/inicjacji bazy przy każdym dbQuery()" a teraz pytasz dlaczego łączenie się z bazą przy każdym zapytaniu ma Ci przeszkadzć :/

Sorry ale ja się poddaje.
Go to the top of the page
+Quote Post
Mayka
post 11.12.2013, 17:51:52
Post #16





Grupa: Zarejestrowani
Postów: 304
Pomógł: 1
Dołączył: 12.01.2009
Skąd: Kanapa

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


Cytat(Methestel @ 11.12.2013, 17:31:54 ) *
Sam się pytasz w pierwszym poście jak zrobić "żeby nie było połączenia/inicjacji bazy przy każdym dbQuery()" a teraz pytasz dlaczego łączenie się z bazą przy każdym zapytaniu ma Ci przeszkadzć :/

Sorry ale ja się poddaje.


Hahaha, chodziło mi bardziej o to, że teraz wiem jak je rozłączyć wiec moge przy każdym pobraniu rozłączyć z bazą i wtedy nie bedzie przekroczenia ilości jednoczesnych połączeń.

Cytat(ctom @ 11.12.2013, 17:30:54 ) *
przecież @Methestel Ci napisał jak tu



A czemu ma mi to przeszkadzać bo nie rozumiem ?


może twój serwer będzie miał coś przeciwko ;-) ? pewnie masz apache , to zrób sobie test wydajności twojego rozwiązania i tego z jednym inicjowanym połączeniem (np. ab -n 1000 -c 10 )

Nie zrobie bo niemam dostępu do tego serwera -zwykły hosting w nazwie.
Go to the top of the page
+Quote Post
Turson
post 11.12.2013, 17:54:45
Post #17





Grupa: Zarejestrowani
Postów: 4 291
Pomógł: 829
Dołączył: 14.02.2009
Skąd: łódź

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


Cytat(Turson @ 10.12.2013, 22:44:25 ) *
tworzysz instancję new PDO i działasz na tym w całym dokumencie.

Go to the top of the page
+Quote Post
Mayka
post 11.12.2013, 17:55:50
Post #18





Grupa: Zarejestrowani
Postów: 304
Pomógł: 1
Dołączył: 12.01.2009
Skąd: Kanapa

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


Cytat(ctom @ 11.12.2013, 17:30:54 ) *
przecież @Methestel Ci napisał jak tu


Czyli dobrze rozumiem że trzeba zrobić to w oop bo inaczej bedzie za każdym dbquery łączył z baza ?

Aha i PdoFactory::closeAll() na samym końcu strony tak ?

Ten post edytował Mayka 11.12.2013, 18:06:21
Go to the top of the page
+Quote Post
Turson
post 11.12.2013, 18:11:47
Post #19





Grupa: Zarejestrowani
Postów: 4 291
Pomógł: 829
Dołączył: 14.02.2009
Skąd: łódź

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


Żadne OOP.
  1. $db = new PDO('mysql:host=;dbname=', '', '', array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'")) or die();

Dalej już wszystkimi zapytaniami operujesz na $db, np. $db->query(...)
Go to the top of the page
+Quote Post
ctom
post 11.12.2013, 18:11:50
Post #20





Grupa: Zarejestrowani
Postów: 321
Pomógł: 55
Dołączył: 19.04.2009

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


powiedz szczerze, nie masz pojęcia co ta klasa PdoFactory robi ?

a z ciekawości po co robisz to Twoje dbquery questionmark.gif wstaw więcej kodu jak możesz


--------------------
Polecam MyDevil hosting idealny dla deweloperów
Go to the top of the page
+Quote Post

2 Stron V   1 2 >
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 Wersja Lo-Fi Aktualny czas: 4.05.2025 - 08:31