Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHP] PDO
Majkelo23
post 23.10.2013, 07:17:21
Post #1





Grupa: Zarejestrowani
Postów: 226
Pomógł: 17
Dołączył: 13.02.2012

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


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

Ten post edytował Majkelo23 23.10.2013, 07:19:31
Go to the top of the page
+Quote Post
nospor
post 23.10.2013, 07:29:56
Post #2





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




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


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

"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
Majkelo23
post 23.10.2013, 07:39:15
Post #3





Grupa: Zarejestrowani
Postów: 226
Pomógł: 17
Dołączył: 13.02.2012

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


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?

Ten post edytował Majkelo23 23.10.2013, 07:40:25
Go to the top of the page
+Quote Post
nospor
post 23.10.2013, 07:49:50
Post #4





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




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


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

"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
Majkelo23
post 23.10.2013, 08:12:47
Post #5





Grupa: Zarejestrowani
Postów: 226
Pomógł: 17
Dołączył: 13.02.2012

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


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ś.
Go to the top of the page
+Quote Post
nospor
post 23.10.2013, 08:24:40
Post #6





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




  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."'");


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

"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
Majkelo23
post 23.10.2013, 09:27:31
Post #7





Grupa: Zarejestrowani
Postów: 226
Pomógł: 17
Dołączył: 13.02.2012

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


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?
Go to the top of the page
+Quote Post
freemp3
post 23.10.2013, 09:38:58
Post #8





Grupa: Zarejestrowani
Postów: 467
Pomógł: 77
Dołączył: 6.09.2008
Skąd: Miechów / Kraków

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


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.


--------------------
Niemożliwym jest stworzenie czegokolwiek idiotoodpornego, ponieważ idioci są wyjątkowo pomysłowi.

https://www.aroch.pl
https://themeforest.net/user/aroch
https://www.astroblog.aroch.pl
https://www.4geeks.pl
Go to the top of the page
+Quote Post
nospor
post 23.10.2013, 09:53:22
Post #9





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




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.


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

"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
Majkelo23
post 23.10.2013, 10:15:31
Post #10





Grupa: Zarejestrowani
Postów: 226
Pomógł: 17
Dołączył: 13.02.2012

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


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() ?
Go to the top of the page
+Quote Post
freemp3
post 23.10.2013, 10:19:32
Post #11





Grupa: Zarejestrowani
Postów: 467
Pomógł: 77
Dołączył: 6.09.2008
Skąd: Miechów / Kraków

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


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


Ten post edytował freemp3 23.10.2013, 10:22:37


--------------------
Niemożliwym jest stworzenie czegokolwiek idiotoodpornego, ponieważ idioci są wyjątkowo pomysłowi.

https://www.aroch.pl
https://themeforest.net/user/aroch
https://www.astroblog.aroch.pl
https://www.4geeks.pl
Go to the top of the page
+Quote Post
Majkelo23
post 23.10.2013, 10:22:58
Post #12





Grupa: Zarejestrowani
Postów: 226
Pomógł: 17
Dołączył: 13.02.2012

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


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.

Ten post edytował Majkelo23 23.10.2013, 10:26:28
Go to the top of the page
+Quote Post
freemp3
post 23.10.2013, 10:25:13
Post #13





Grupa: Zarejestrowani
Postów: 467
Pomógł: 77
Dołączył: 6.09.2008
Skąd: Miechów / Kraków

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


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


--------------------
Niemożliwym jest stworzenie czegokolwiek idiotoodpornego, ponieważ idioci są wyjątkowo pomysłowi.

https://www.aroch.pl
https://themeforest.net/user/aroch
https://www.astroblog.aroch.pl
https://www.4geeks.pl
Go to the top of the page
+Quote Post
ber32
post 23.10.2013, 19:57:40
Post #14





Grupa: Zarejestrowani
Postów: 332
Pomógł: 22
Dołączył: 6.07.2010

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


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


--------------------
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 Wersja Lo-Fi Aktualny czas: 5.07.2025 - 00:16