Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] PDO
Forum PHP.pl > Forum > Przedszkole
Majkelo23
Witam!

Próbuję pojąć PDO. We wszystkich tutoriali w necie wynika, że ile razy wykonujemy zapytanie - tyle razy należy się łączyć z bazą danych... Wydaje mi się, że raczej tak nie jest bo to byłoby niewygodne.

Czy wykonanie takiego kodu:
  1. try
  2. {
  3. $db = new PDO('mysql:host='.DB_SERVER.';dbname='.DB_DATABASE.';encoding=utf8', DB_USERNAME, DB_PASSWORD);
  4. }
  5. catch(PDOException $e)
  6. {
  7. die('Połączenie nie mogło zostać utworzone: ' . $e->getMessage());
  8. }]


RAZ wystarczy, aby nawiązać połączenie, a potem można się już swobodnie odwoływać do zmiennej $db, np:
  1. $sql = $db->exec("SELECT * FROM `oop_users` WHERE username = '".$username."' OR user_email = '".$email."'");
  2. if ( $sql > 0 )
  3. {
  4. return FALSE;
  5. }
  6. else
  7. {
  8. return TRUE;
  9. }

?
Czy raczej powinienem to zapisać tak:

  1. try
  2. {
  3. $db = new PDO('mysql:host='.DB_SERVER.';dbname='.DB_DATABASE.';encoding=utf8', DB_USERNAME, DB_PASSWORD);
  4. $sql = $db->exec("SELECT * FROM `oop_users` WHERE username = '".$username."' OR user_email = '".$email."'");
  5. if ( $sql > 0 )
  6. {
  7. return FALSE;
  8. }
  9. else
  10. {
  11. return TRUE;
  12. }
  13. }
  14. catch(PDOException $e)
  15. {
  16. die('Połączenie nie mogło zostać utworzone: ' . $e->getMessage());
  17. }]


czyli co zapytanie, powtarzać cały scenariusz dot. łączenia się z bazą, wykonywania zapytań, zwracania ew. błędów itd. ?
nospor
Nie wiem jakie ty tutki czytasz, ale moze czas przerzucic sie na inne? wink.gif

Z baza masz sie laczyc raz, a potem korzystac z tego polaczenia gdzie ci sie podoba
Identycznie jak ze starym poczciwym mysql_connect, ktore robi sie raz a nie za kazdym razem gdy chce sie wykonac zapytanie
Majkelo23
http://pl.wikibooks.org/wiki/PHP/Biblioteka_PDO

Zauważ, że nie ma tam nigdzie przykładu, gdzie łączymy się z bazą danych, a później operujemy na tym jednym połączeniu. Cały czas jest sztywny scenariusz:

  1. try
  2. {
  3. // łączenie z bazą
  4. // zapytanie
  5.  
  6. // bind lub podobne
  7.  
  8. }
  9. catch(PDOException $e)
  10. {
  11. die('fail->'.$e);
  12. }


No, ale skoro jest jak mówisz to super Lkingsmiley.png

Mam jeszcze jedno pytanie - mam dwie klasy:
- db,
- users.

Klasa db wygląda tak:

  1. class db
  2. {
  3. function __construct()
  4. {
  5. try
  6. {
  7. $db = new PDO('mysql:host='.DB_SERVER.';dbname='.DB_DATABASE.';encoding=utf8', DB_USERNAME, DB_PASSWORD);
  8. }
  9. catch(PDOException $e)
  10. {
  11. die('Połączenie nie mogło zostać utworzone: ' . $e->getMessage());
  12. }
  13. }
  14. }


czyli łączy się z bazą danych, natomiast klasa users rozpoczyna się tak:

  1. class users
  2. {
  3.  
  4. function __construct()
  5. {
  6. $db = new db;
  7. }


czyli tworzę nowy obiekt klasy db pod zmienną $db. Potem poniżej w kodzie jednej z metod, próbuję się do tego odwołać tak:

  1. // sprawdzamy czy podany nick lub email juz istnieje w bazie
  2. try
  3. {
  4. $sql = $db->exec("SELECT * FROM `oop_users` WHERE username = '".$username."' OR user_email = '".$email."'");
  5. if ( $sql > 0 )
  6. {
  7. return TRUE;
  8. }
  9. else
  10. {
  11. return FALSE;
  12. }
  13. }
  14. catch(PDOException $e)
  15. {
  16. die('Połączenie nie mogło zostać utworzone: ' . $e->getMessage());
  17. }


Otrzymuję:


Fatal error: Call to a member function exec() on a non-object in /home/majkelo/public_html/OOP/includes/users.class.php on line 50

Możesz mnie uświadomić, gdzie robię jakiś głupi błąd?
nospor
Cytat
Zauważ, że nie ma tam nigdzie przykładu, gdzie łączymy się z bazą danych, a później operujemy na tym jednym połączeniu. Cały czas jest sztywny scenariusz:
Koles poprostu pisal kazdy kod jako oddzielny kawalek, by kazdy mogl sobie odpalic kazdy kod bez zastanawiania sie czemu nie dziala. A niestety jest cala masa geniuszy, ktorzy by wzieli trzeci kod bez zrobienia polaczenia, ktore bylo w pierwszym kodzie

Co do bledu:
1)Zajrzyj do manuala i poczytaj o zasiegu zmiennych.
2)Albo skoro uzywasz klas i obiektow to zainteresuj sie $this
3) No i pozatym dla obietku user masz przekazac gotowy obiekt $db a nie tworzyc go od nowa. Dzieki temu taki obiekt mozesz przekazac roznym klasom a nie dla kazdej klasy tworzyc db od nowa.

ad1) http://php.net/manual/pl/language.variables.scope.php
ad2) http://www.php.net/manual/en/language.oop5.basic.php
http://www.php.net/manual/en/language.oop5.properties.php
Majkelo23
o całym OOP czytam od wczoraj, także cudów się nie spodziewałem.
Zapomniałem dodać, że przed całym zapisem:

  1. class users {


jest includowany plik db.class.php.

Co do $this, to wiem, że wskazuje zawsze na obiekt, na którym daną metodę wywołujemy.
Jednak nie rozumiem tego zdania z Twojej wypowiedzi:
Cytat
3) No i pozatym dla obietku user masz przekazac gotowy obiekt $db a nie tworzyc go od nowa. Dzieki temu taki obiekt mozesz przekazac roznym klasom a nie dla kazdej klasy tworzyc db od nowa.


a z pozoru wygląda całkiem ciekawie, więc czy mógłbyś mi jeszcze zaprezentować jakiś przykład dot. tego co wyżej zacytowałem (chociażby z manuala) ? Bo kompletnie nie wiem o czym mówisz, a może wiem, ale nie potrafię się domyślić, bazując na tym co napisałeś.
nospor
  1. //gdzies tam w odmetach kosmosu tworzysz sobie obiekt $db
  2. $db =new db();
  3.  
  4. //I teraz ten obiekt przekazzujesz do dowolnej klasy jakiej potrzebujesz
  5.  
  6. $user = new user($db);


Gdzie user wyglada tak:
  1. class users
  2.  
  3. {
  4.  
  5. private $db;
  6.  
  7. function __construct($db)
  8.  
  9. {
  10.  
  11. $this->db = $db;
  12.  
  13. }
  14.  
  15. // i gdzies tam w klasie user masz miec:
  16. $sql = $this->db->exec("SELECT * FROM `oop_users` WHERE username = '".$username."' OR user_email = '".$email."'");
Majkelo23
Wszystko spoko, ale moja tępota w temacie OOP nadal robi swoje... wink.gif

db.class.php:

  1. class db
  2. {
  3. function __construct()
  4. {
  5. try
  6. {
  7. $db = new PDO('mysql:host='.DB_SERVER.';dbname='.DB_DATABASE.';encoding=utf8', DB_USERNAME, DB_PASSWORD);
  8. }
  9. catch(PDOException $e)
  10. {
  11. die('Połączenie nie mogło zostać utworzone: ' . $e->getMessage());
  12. }
  13. }
  14. }


common.php:

  1. <?php
  2. include('includes/db.class.php');
  3. $db = new db();
  4. include('includes/users.class.php');
  5.  
  6. ?>


index.php:
  1. <?php
  2. include('common.php');
  3. $user = new user($db);
  4.  
  5. if ( $user->check_values('Majkelo', 'email@gmail.com') )
  6. {
  7. echo 'istnieje';
  8. }
  9. else
  10. {
  11. echo 'nie istnieje';
  12. }
  13.  
  14. ?>


i część klasy users.class.php:

  1. class user
  2. {
  3. private $db;
  4.  
  5. function __construct($db)
  6. {
  7. $this->db = $db;
  8. }
  9.  
  10. public function check_values($username, $email)
  11. {
  12. if ( !$this->validate_email($email) )
  13. {
  14. return FALSE;
  15. }
  16. else if ( !$this->validate_username($username) )
  17. {
  18. return FALSE;
  19. }
  20.  
  21. // sprawdzamy czy podany nick lub email juz istnieje w bazie
  22. try
  23. {
  24. $sql = $this->db->exec("SELECT * FROM `oop_users` WHERE username = '".$username."' OR user_email = '".$email."'");
  25. if ( $sql > 0 )
  26. {
  27. return TRUE;
  28. }
  29. else
  30. {
  31. return FALSE;
  32. }
  33. }
  34. catch(PDOException $e)
  35. {
  36. die('Połączenie nie mogło zostać utworzone: ' . $e->getMessage());
  37. }
  38. }


efekt wywolania index.php:


Fatal error: Call to undefined method db::exec() in /home/majkelo/public_html/OOP/includes/users.class.php on line 50

Co znowu pomyliłem?
freemp3
Może dlatego, że klasa db nie ma takiej metody. Wywołanie exec powinno zostać wywołane na obiekcie PDO, a nie db.
Tak jak pisał @nospor poczytaj o zasięgu zmiennych.
nospor
Tak napisal freemp3 klasa DB nie ma metody EXEC.

Poza tym, tworząc obiekt PDO w klasie DB, to tez masz go przypisywac do $this->db, w przeciwnym wypadku stracisz go.

Zamiast brac sie za pisanie skryptow przy pomocy klas, to wez zapoznaj sie wpierw z podstawaami klas, popisz rozne przyklady, potem skacz do glebokiej wody.
Majkelo23
Strasznie skomplikowane. Przecież, abym mógł wykonać zapytanie do bazy danych, muszę operować na połączeniu z bazą z klasy db. Z kolei klasa db nie posiada metody exec, bo posiada ją klasa pdo.
Tak więc powinienem odwołać się do klasy db, a dopiero z klasy db kierować się do pdo i operując już na klasie pdo, odwołać się do metody exec... ? $this->db->pdo->exec() ?
freemp3
Cytat
Strasznie skomplikowane

Uwierz mi, że jest to proste. Trzeba tylko poznać zasady działania klas, komunikacji między nimi i zasięgu zmiennych. Bez tej wiedzy nie ma się co zabierać za klasy. Dobrze było by też poznać wzorce takie jak singleton i rejestr. W przypadku baz danych są bardzo przydatne.

Cytat
$this->db->pdo->exec()

Możesz tak zrobić, ale w tedy w klasie db powinno się znaleźć pole pdo i tworząc połączenie rezultat powinien być zapisany właśnie w nim:
  1. class db
  2. {
  3. public $pdo;
  4. function __construct()
  5. {
  6. try
  7. {
  8. $this->pdo = new PDO('mysql:host='.DB_SERVER.';dbname='.DB_DATABASE.';encoding=utf8', DB_USERNAME, DB_PASSWORD);
  9. }
  10. catch(PDOException $e)
  11. {
  12. die('Połączenie nie mogło zostać utworzone: ' . $e->getMessage());
  13. }
  14. }
  15. }
Majkelo23
Cóż, spotkałeś się z jakimiś stronami, gdzie te wątki były poruszone, a nie tylko 'cmoknięte' na sucho dwa zdania i jeden przykład?

EDIT:

To co podałeś działa świetnie, dzięki. Ale i tak wnioskuję po tym wszystkim, że nic z tego nie rozumiem, czas chyba cofnąć się do żmudnej teorii.
freemp3
Pierwsze dwa z brzegu:
http://pl.wikibooks.org/wiki/PHP/Klasy_i_obiekty
http://php.net/manual/pl/book.classobj.php
Poza tym ćwiczyć i jeszcze raz ćwiczyć. Drobnymi kroczkami, bez rzucania się od razu na głęboką wodę.
ber32
Witam. Zapoznaj się też z innym rodzajem połączenia.
np takim
  1. class DBBER extends PDO
  2. {
  3. private $engine = 'mysql';
  4. private $host = 'localhost';
  5. private $port = 3306;
  6. private $database = 'pdo';
  7. private $user = 'root';
  8. private $pass = ''; // password
  9. private $dns;
  10. private $DbPrefix = 'prk_';
  11.  
  12.  
  13.  
  14. public function __construct()
  15. {
  16. try{
  17. if(!empty($this->database))
  18. {
  19. $this->dns = $this->engine.':host='.$this->host.';port='.$this->port.';dbname='.$this->database.';';
  20. parent::__construct($this->dns, $this->user, $this->pass, array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''));
  21. }
  22.  
  23. }catch(PDOException $e){
  24. echo 'The connection could not be established.<br />'.$e->getMessage().'<br />'.strval($e->getCode()).'<br />'.$e->getFile().'<br />'.
  25. $e->getTrace().'<br />'.strval($e->getLine()).'<br />'.$e->getPrevious();
  26. }
  27. }
  28.  
  29. public function dbprefix()
  30. {
  31. return $this->DbPrefix;
  32. }
  33. }
  34.  

zobacz jakie są różnice pomiędzy jednym a drugim

tutaj link do całości sposób wywołania
http://www.phpclasses.org/browse/file/47183.html
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.