Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]PDO przekazywanie uchwytu do klasy
Forum PHP.pl > Forum > Przedszkole
pr0kt0r
W jaki sposób mam przekazać uchwyt połączenia stworzonego w PDO do klasy. Tak abym w całej klasie mógł z niej korzystać nie tworząc cały czas nowego.

Przykład
plik: db_connect.php
  1. <?php
  2. // ...
  3. try {
  4.    $connect = new PDO("mysql:host=localhost;dbname=php", $username, $password);
  5. }catch(PDOException $e) {
  6.  
  7.    echo "Error: " . $e->getMessage() . "<br/>";
  8.  
  9. }
  10. ?>


i TODOList.php

  1. <?php
  2. include("db_connect.php");
  3.  
  4. class TODOListModel {
  5.    private $dbh; // zmienna w której chcę przechowywać uchwyt połączenia
  6.  
  7.    public function _construct($connection){
  8.  
  9.        $this->dbh = $connection ;
  10.  
  11.    }
  12.    public function add_note($text, $author){
  13.  
  14.        $this->dbh->query("INSERT INTO todolist SET date=NOW(),
  15.                           content='$text', author='$author'");
  16.  
  17.    }
  18.    public function get_note(){
  19.  
  20.        //...
  21.  
  22.    }
  23.    public function delete_note(){
  24.  
  25.        //...
  26.  
  27.    }
  28.  
  29. }
  30.  
  31. class TODOListController  {
  32.  
  33. }
  34.  
  35. $obj = new TODOListModel($connect);
  36. $obj->add_note("Zrob pranie", "Krzysiek") or die("błąd");
  37. ?>


I w funkcji add_note wyskakuje mi błąd
Fatal error: Call to a member function query() on a non-object in C:\xampp\htdocs\todolist\TODOList.php on line 25


Wybaczcie ale uczę się dopiero programować obiektowo ta klasa to tak jakby ćwiczenie.
Vielta
Zmień _construct na __construct (2x_)
pr0kt0r
Przekształciłem kod

  1. <?php
  2.  
  3. class iPDO extends PDO {
  4.  
  5.    public function __construct($host, $login, $pass){
  6.  
  7.        new PDO("mysql:host=$host;dbname=php", $login, $pass);
  8.  
  9.    }
  10.  
  11. }
  12. class TODOListModel  {
  13.    private $dbh;
  14.    public function __construct(iPDO $db){
  15.  
  16.        $this->dbh = $db ;
  17.  
  18.    }
  19.    public function add_note($text, $author){
  20.  
  21.        $this->dbh->query("INSERT INTO todolist SET date=NOW(),    // Linia w której jest błąd
  22.                           content='$text', author='$author'");
  23.  
  24.    }
  25.     // ...
  26.  
  27. }
  28.  
  29. class TODOList  {
  30.  
  31. }
  32. $dbh = new iPDO("localhost", "root", "");
  33. $obj = new TODOListModel($dbh) ;
  34. $obj->add_note("Zrob pranie", "Krzysiek");
  35.  
  36. ?>


Niestety nadal nie mogę nic zrobić. Teraz pokazuje mi błąd: Warning: PDO::query() [pdo.query]: SQLSTATE[00000]: No error: PDO constructor was not called in C:\xampp\htdocs\todolist\TODOList.php on line 30

Vielta, dzięki ale to nie wina tego. U siebie w edytorze miałem dobrze, przypadkiem musiałem skasować jedną dolna spacje.
erix
  1. <?php
  2. new PDO("mysql:host=$host;dbname=php", $login, $pass);
  3. ?>

Skoro to instancjujesz, to może by się przydało ten uchwyt zachować?

Cytat
No error: PDO constructor was not called in C:\xampp\htdocs\todolist\TODOList.php on line 30

Dodaj konstrukcję rodzica w klasie rozszerzającej:
  1. <?php
  2. parent::__construct();
  3. ?>
pr0kt0r
erix, wkońcu zaczeło działać. Działa tylko bez tego parent::__construct(), gdy to dodaje pojawia się błąd:
Cytat
Warning: PDO::__construct() expects at least 1 parameter, 0 given in C:\xampp\htdocs\todolist\TODOList.php on line 15

Catchable fatal error: Argument 1 passed to TODOListModel::__construct() must be an instance of iPDO, null given, called in C:\xampp\htdocs\todolist\TODOList.php on line 52 and defined in C:\xampp\htdocs\todolist\TODOList.php on line 24


Tu akurat jest bez argumentów, ale próbowałem dać w parent::__construct("mysql:host=$host;dbname=php",$login, $pass); i wtedy żadnego błędu już nie pokazuje lecz niestety nie dodaje rekordu do bazy.

Tak czy inaczej WIELKIE DZIĘKI za pomoc guitar.gif czarodziej.gif party.gif

Kod który działa:

  1. <?php
  2.  
  3. class iPDO extends PDO {
  4.    public $cdbh;
  5.    public function __construct($host, $login, $pass){
  6.  
  7.        //parent::__construct();
  8.        $this->cdbh = new PDO("mysql:host=$host;dbname=php",
  9.                               $login, $pass);
  10.      
  11.    }
  12.  
  13. }
  14. class TODOListModel  {
  15.    private $dbh;
  16.    public function __construct(iPDO $db){
  17.  
  18.        $this->dbh = $db->cdbh;
  19.  
  20.    }
  21.    public function add_note($text, $author){
  22.  
  23.        $this->dbh->query("INSERT INTO todolist SET date=NOW(),
  24.                           content='$text', author='$author'");
  25.  
  26.    }
  27. }
  28.  
  29. class TODOList  {
  30.  
  31. }
  32. $dbh = new iPDO("localhost", "root", "");
  33. $obj = new TODOListModel($dbh);
  34. $obj->add_note("Zrob pranie", "Krzysiek");
  35.  
  36. ?>
Crozin
Po co tworzysz klasę iPDO która nie robi kompletnie nic?
pr0kt0r
To może powiedz mi jak mam to zrobić inaczej bo próbowałem również zrobić to na inne sposoby między innymi w taki:

  1. <?php
  2. class TODOListModel  {
  3.    private $dbh;
  4.    public function __construct(PDO $db){
  5.  
  6.        $this->dbh = $db;
  7.  
  8.    }
  9.    public function add_note($text, $author){
  10.        $this->dbh->query("INSERT INTO todolist SET date=NOW(),
  11.                                      content=$text, author=$author");
  12.  
  13.    }
  14. }
  15.  
  16. class TODOList  {
  17.  
  18. }
  19. $dbh = new PDO("mysql:host=localhost;dbname=php", "root", "");
  20. $obj = new TODOListModel($dbh);
  21. $obj->add_note("Wynieś śmieci", "Krzysiek");
  22. ?>


Niestety ten kod nie działa. Nie pokazuje się żaden błąd ale nie dodaje danych do tabeli.
Crozin
1) PDO rzuca wyjątkami, gdzie masz bloki try i catch?
2) Twoje zapytanie jest niepoprawne, wygląda ono tak:
  1. INSERT INTO todolist SET date=NOW(), content=Wynieś śmieci, author=Krzysiek
Tekst wstawiamy w cudzysłowie.
3) Włącz raportowanie błędów bo pewnie teraz wywala Ci FATALa, że nie obsłużyłeś wyjątku.
pr0kt0r
Crozin, w normalnym kodzie obsługuje wyjątki z PDOEXpection(kod umieszczony w pierwszym poście to dowodzi). Nie używam również metody query lecz prepare, bindParam i execute więc cudzysłowia nie są mi potrzebne przez co w tym przykładzie zwyczajnie o nich zapomniałem.
Crozin
No to pokaż kod w takiej postaci w jakiej go masz i w jakiej niby nie działa.
pr0kt0r
No ok, ale po co?

  1. <?php
  2.  
  3. /**
  4.  * Description of TODOList
  5.  *
  6.  * TODOList is simple class for generate short note about future work
  7.  *
  8.  * @author Kri normal
  9.  */
  10.  
  11. class iPDO extends PDO {
  12.    public $cdbh;
  13.    public function __construct($host, $login, $pass){
  14.        try{
  15.            $this->cdbh = new PDO("mysql:host=$host;dbname=php",
  16.                                   $login, $pass);
  17.        } catch(PDOException $e) {
  18.  
  19.            echo "Error!: " . $e->getMessage() . "<br/>";
  20.  
  21.        }
  22.      
  23.    }
  24.  
  25. }
  26.  
  27. /*
  28.  *
  29.  * var @peq - prepare and execute query
  30.  *
  31.  */
  32. class TODOListModel  {
  33.    private $dbh;
  34.    public function __construct(iPDO $db){
  35.  
  36.        $this->dbh = $db->cdbh;
  37.  
  38.    }
  39.  
  40.    public function add_note($text, $author){
  41.        try {
  42.  
  43.            $sql = "INSERT INTO todolist SET date=NOW(),
  44.                    content=:content, author=:author";
  45.            $peq = $this->dbh->prepare($sql);
  46.            $peq->bindParam(':content', $text, PDO::PARAM_STR);
  47.            $peq->bindParam(':author', $author, PDO::PARAM_STR);
  48.            $peq->execute();
  49.  
  50.        } catch(PDOException $e) {
  51.  
  52.            echo "Error!: " . $e->getMessage() . "<br/>";
  53.  
  54.        }
  55.        $this->dbh->query("INSERT INTO todolist SET date=NOW(),
  56.                    content=$text, author=$author");
  57.  
  58.    }
  59.    public function get_note(){
  60.  
  61.        $sql = "SELECT date, content, author FROM todolist";
  62.        $peq = $this->dbh->prepare($sql);
  63.        $peq->execute();
  64.        
  65.    }
  66.    public function delete_note(){
  67.  
  68.        //mysql_delete();
  69.  
  70.    }
  71.  
  72. }
  73.  
  74. class TODOList  {
  75.  
  76. }
  77. $dbh = new iPDO("localhost", "root", "");
  78. $obj = new TODOListModel($dbh);
  79. $obj->add_note("Wynieś śmieci", "Krzysiek");
  80.  
  81. ?>


Mógłbyś mi teraz powiedzieć co wg. ciebie jest nie tak z klasą iPDO. Czemu ona nic nie robi? Jak już wcześniej napisałem jestem "świeży" w OOP nie jeszcze wielu rzeczy...
antyqjon
Zdecyduj się co do iPDO - dziedziczenie czy kompozycja.
Crozin
Cytat
Czemu ona nic nie robi?
No a zastanów się... co takiego niby robi ta klasa?
pr0kt0r
Crozin, ok masz pełną rację. Ostatecznie zrezygnowałem z klasy iPDO i po prostu w konstruktorze klasy TODOListModel jako parametr pobieram obiekt PDO(czyli uchwyt do bazy). Wcześniej już tak robiłem niestety popełniłem wielki błąd mianowicie nie ustawiłem id tabeli auto_increment co spowodowało te wszystkie problemy hehe winksmiley.jpg Ale przynajmniej trochę się nauczyłem.

antyqjon, ostatecznie i definitywnie kompozycja ale iPDO już nie ma smile.gif

Wielkie dzięki za pomoc.
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.