Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] Call to a member function prepare() on a non-object
Forum PHP.pl > Forum > Przedszkole
troian
Tak jak w tytule tematu, skrypt zwraca mi błąd:

Kod
Fatal error: Call to a member function prepare() on a non-object in include.db.php on line 33


  1. class db
  2. {
  3. protected static $host;
  4. protected static $port;
  5. protected static $user;
  6. protected static $pass;
  7. private static $pdo;
  8.  
  9. public function __construct()
  10. {
  11. self::$host = HOST;
  12. self::$port = PORT;
  13. self::$user = USER;
  14. self::$pass = PASS;
  15. $options = array(
  16. PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES UTF8'
  17. );
  18. try
  19. {
  20. self::$pdo = new PDO("mysql:host={self::$host};port={self::$port}", self::$user, self::$pass, $options);
  21. self::$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  22. }
  23. catch(PDOException $error)
  24. {
  25. die("ERROR CONNECT: " . $error->getMessage());
  26. }
  27. }
  28.  
  29. public static function query($query='',$value=array(),$type="true")
  30. {
  31. try
  32. {
  33. $query = self::$pdo->prepare($query);
  34. switch($type)
  35. {
  36. case 'true':
  37. case 'false':
  38. $tab = array('true' => array(0 =>'true',1=>'false'),'false' => array(0 =>'false',1=>'true'));
  39. $result = $query->execute($value) ? $tab[$type][0] : $tab[$type][1];
  40. break;
  41. default:
  42. $result = $query->execute($value) ? $query->$type() : false;
  43. }
  44. }
  45. catch(PDOException $error)
  46. {
  47. die("ERROR QUERY: " . $error->getMessage());
  48. }
  49.  
  50. return $result;
  51. }
  52. }
  53.  


dokładnie chodzi o tą oto linijkę
Kod
$query = self::$pdo->prepare($query);
nospor
Sie zdecyduj. Albo uzywasz STATIC albo normalnie obiektow. Bo self::$pdo inicjalizujesz w konstruktorze, ale konstruktor odpala sie tylko dla obiektow a ty masz funkcje statyczna:
public static function query
ktora pewnie tez odpalasz jaka statyczna.
troian
Cytat(nospor @ 23.06.2016, 14:40:23 ) *
Sie zdecyduj. Albo uzywasz STATIC albo normalnie obiektow. Bo self::$pdo inicjalizujesz w konstruktorze, ale konstruktor odpala sie tylko dla obiektow a ty masz funkcje statyczna:
public static function query
ktora pewnie tez odpalasz jaka statyczna.


Racja mój błąd, przerobiłem to w taki oto sposób

  1. class db
  2. {
  3. private $pdo;
  4.  
  5. public function __construct()
  6. {
  7. $options = array(
  8. PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES UTF8'
  9. );
  10. try
  11. {
  12. $this->pdo = new PDO("mysql:host={HOST};port={PORT}", USER, PASS, $options);
  13. $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  14. }
  15. catch(PDOException $error)
  16. {
  17. die("ERROR CONNECT: " . $error->getMessage());
  18. }
  19. }
  20.  
  21. public function query($query='',$value=array(),$type="true")
  22. {
  23. try
  24. {
  25. $db = new db();
  26. $query = $db->pdo->prepare($query);
  27. switch($type)
  28. {
  29. case 'true':
  30. case 'false':
  31. $tab = array('true' => array(0 =>'true',1=>'false'),'false' => array(0 =>'false',1=>'true'));
  32. $result = $query->execute($value) ? $tab[$type][0] : $tab[$type][1];
  33. break;
  34. default:
  35. $result = $query->execute($value) ? $query->$type() : false;
  36. }
  37. }
  38. catch(PDOException $error)
  39. {
  40. die("ERROR QUERY: " . $error->getMessage());
  41. }
  42.  
  43. return $result;
  44. }
  45. }
  46.  


Teraz chyba jest dobrze napisane.
nospor
Nie, nie jest dobrze napisane....

Po grzyba w query robisz
$db = new db();
przeciez tworzysz ten sam obiekt w tej samej klasie...

Obiekt pdo stworzyles raz w konstruktorze i to z niego masz korzystac a nie tworzyc nowe dziekie kombinacje
troian
to w jaki sposób wywołać obiekt pdo ? $this->pdo nie działa
nospor
Pokaz jak odpalasz funckje query(). I ogolnie pokaz caly kod
LowiczakPL
No więc na szybko wink.gif


metoda query jest statyczna a w niej

self::$pdo po prostu nie istnieje bo KONSTRUKTOR nie jest wykonany exclamation.gif!

Jeśli chcesz robić statyczną klasę do obsługi bazy to nie w konstruktorze jest łączenie z bazą a w statycznej metodzie

np statyczna klasa implementująca PDO

  1. use PDO;
  2.  
  3. class Database extends PDO
  4. {
  5. public static function get($confi = false)
  6. {
  7. $confi = !$confi ? array (
  8. 'type' => DB_TYPE,
  9. 'host' => DB_HOST,
  10. 'name' => DB_NAME,
  11. 'user' => DB_USER,
  12. 'pass' => DB_PASS
  13. ) : $group;
  14.  
  15. $type = $confi['type'];
  16. $host = $confi['host'];
  17. $name = $confi['name'];
  18. $user = $confi['user'];
  19. $pass = $confi['pass'];
  20.  
  21. $id = "$type.$host.$name.$user.$pass";
  22. if (isset(self::$instances[$id])) {
  23. return self::$instances[$id];
  24. }
  25.  
  26. try {
  27. $instance = new Database("$type:host=$host;dbname=$name;charset=utf8", $user, $pass);
  28. $instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  29. self::$instances[$id] = $instance;
  30. return $instance;
  31. } catch (PDOException $e) {
  32. Logger::newMessage($e);
  33. Logger::customErrorMsg();
  34. }
  35. }



i wywołujesz to sobie w dowolnym modelu

  1. class Model {
  2. protected $_db;
  3.  
  4. public function __construct(){
  5. $this->_db = Database::get(); // to jest Twoje połączenie z bazą za pomocą PDO
  6. }
  7.  
  8. public function insert($table, $array){
  9. return $this->_db->insert($table,$array);
  10. }
  11.  
  12. ....
troian
Wykonałem to w taki sposób,

Czy jest to prawidłowe ?

  1. class db
  2. {
  3. public function connect()
  4. {
  5. $host = HOST;
  6. $port = PORT;
  7. $user = USER;
  8. $pass = PASS;
  9. $options = array(
  10. PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES UTF8'
  11. );
  12. try
  13. {
  14. $connect = new PDO("mysql:host={$host};port={$port}", $user, $pass, $options);
  15. $connect->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  16. return $connect;
  17. }
  18. catch(PDOException $error)
  19. {
  20. die("ERROR CONNECT: " . $error->getMessage());
  21. }
  22. }
  23.  
  24. public function query($query='',$value=array(),$type="true",$cashe=0)
  25. {
  26. try
  27. {
  28. $query = db::connect()->prepare($query);
  29. switch($type)
  30. {
  31. case 'true':
  32. case 'false':
  33. $tab = array('true' => array(0 =>'true',1=>'false'),'false' => array(0 =>'false',1=>'true'));
  34. $result = $query->execute($value) ? $tab[$type][0] : $tab[$type][1];
  35. break;
  36. default:
  37. $result = $query->execute($value) ? $query->$type() : false;
  38. }
  39. }
  40. catch(PDOException $error)
  41. {
  42. die("ERROR QUERY: " . $error->getMessage());
  43. }
  44.  
  45. return $result;
  46. }


funkcję query wykonuje tak:
  1. db::query('SELECT * FROM `'.CMS.'`.`web_config`',array(),'fetch');


nospor
Cos ty sie uparl na tworzenie tych obiektow?

W konstruktorze masz raz utworzyc obiekt $pdo a potem wszedzie indziej tylko
$this->pdo

Jesli ci nie dzialalo znaczy ze zrobiles to zle wczesniej. Dlatego prosilem o kod. No ale widze swoje wiesz lepiej...

edit:

db::query
To jest wywoalnie statycznie. query ma byc wywolywane tak: $db->query gdzie $db =new db(). Temu ci wczesniej nie dzialalo $this->pdo bo co ty odpalales ciagle metody statyczne. Zapomnij na tym etapie o metodach statycznych tylko uzywaj normalnie obiektow
troian
Cytat(nospor @ 24.06.2016, 15:26:58 ) *
Cos ty sie uparl na tworzenie tych obiektow?

W konstruktorze masz raz utworzyc obiekt $pdo a potem wszedzie indziej tylko
$this->pdo

Jesli ci nie dzialalo znaczy ze zrobiles to zle wczesniej. Dlatego prosilem o kod. No ale widze swoje wiesz lepiej...


no ale kiedy robię to w taki sposób:

  1. class db
  2. {
  3.  
  4. protected $pdo;
  5.  
  6. public function __Construct()
  7. {
  8. $host = HOST;
  9. $port = PORT;
  10. $user = USER;
  11. $pass = PASS;
  12. $options = array(
  13. PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES UTF8'
  14. );
  15. try
  16. {
  17. $this->pdo = new PDO("mysql:host={$host};port={$port}", $user, $pass, $options);
  18. $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  19. }
  20. catch(PDOException $error)
  21. {
  22. die("ERROR CONNECT: " . $error->getMessage());
  23. }
  24. }
  25.  
  26. public function query($query='',$value=array(),$type="true")
  27. {
  28. try
  29. {
  30. $query = $this->pdo->prepare($query);
  31. switch($type)
  32. {
  33. case 'true':
  34. case 'false':
  35. $tab = array('true' => array(0 =>'true',1=>'false'),'false' => array(0 =>'false',1=>'true'));
  36. $result = $query->execute($value) ? $tab[$type][0] : $tab[$type][1];
  37. break;
  38. default:
  39. $result = $query->execute($value) ? $query->$type() : false;
  40. }
  41. }
  42. catch(PDOException $error)
  43. {
  44. die("ERROR QUERY: " . $error->getMessage());
  45. }
  46.  
  47. return $result;
  48. }
  49. }


zwraca mi błąd
Kod
Using $this when not in object context


chodzi o tą linijkę:
  1. $query = $this->pdo->prepare($query);


Nie wiem może jestem jakiś tępy albo coś ale nie rozumiem gdzie robię błąd sad.gif
nospor
Wszystko dlatego ze query odpalassz statycznie: db::query

Mowie ci: zrob to normalny obiekt z tego - to sa naprawde podstawy obiektow, przez ktore w ogole nie przeszedles :/

  1.  
  2. $db = new db();
  3. db->query(...);
troian
No ale jeżeli 10-15 plików będzie się tak generować to będzie zwalniać stronę chyba i dlatego statycznie chciałem to napisać.

chyba że, się mylę w tej kwestii to popraw mnie smile.gif
nospor
Obiekt db tworzy sie tylko i wylacznie RAZ.
Raz utworzony obiekt db przekazuje sie tylko wszedzie tam gdzie potrzeba. Poczytaj o wzorcu DI (Dependency Injection)
troian
Cytat(nospor @ 24.06.2016, 17:29:44 ) *
Obiekt db tworzy sie tylko i wylacznie RAZ.
Raz utworzony obiekt db przekazuje sie tylko wszedzie tam gdzie potrzeba. Poczytaj o wzorcu DI (Dependency Injection)


no ale przy każdym załadowaniu strony jest generowane połączenie do bazy chyba tak ?
viking
To zależy. Jest możliwość wykonania "lazy loading" czyli zainicjowanie klasy tylko jeśli jest potrzebna.
Możesz sobie zerknąć np. w kod https://github.com/zendframework/zend-servicemanager oraz jego dokumentację.
troian
To w jaki sposób działa to w joomli ? bo ja własnie starałem bazować się na jej kodzie.
Pyton_000
Zmień obiekt zainteresowania (czy. Jomla)
troian
Cytat(Pyton_000 @ 25.06.2016, 10:18:34 ) *
Zmień obiekt zainteresowania (czy. Jomla)


Na czym mogę bazować?
viking
Podałem ci już link. Zobacz inne komponenty typu zend db. Zainteresuj sie dobrze napisanymi frameworkami typu symfony, zend. Ucz się od najlepszych a nie z tego syfu jomli.
Zobacz ostatnie artykuły z mojej stopki. Ostatnio pisałem jak wykorzystywać komponenty zenda we własnych projektach.
troian
Cytat(viking @ 25.06.2016, 11:19:04 ) *
Podałem ci już link. Zobacz inne komponenty typu zend db. Zainteresuj sie dobrze napisanymi frameworkami typu symfony, zend. Ucz się od najlepszych a nie z tego syfu jomli.
Zobacz ostatnie artykuły z mojej stopki. Ostatnio pisałem jak wykorzystywać komponenty zenda we własnych projektach.


Dzięki wielkie zaraz sobie pobiorę i zobaczę jak to działa :-)
com
LowiczakPL a Ty jak chcesz pomagać, to czytaj uważnie, bo kod już dawno nie był statyczny i autor by sobie poradził, gdybyś nie wprowadzał w błąd jego wink.gif
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.