Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Wykorzystanie atrybutu innej klasy
Forum PHP.pl > Forum > PHP
Kmaciek
Cześć wszystkim,

Zaczynam zabawę z obiektowym PHP i nadziałem się na pierwszy problem, z którym nie mogę sobie poradzić (google też nie pomogło ani przeszukanie forum). Otóż na mojej stronie mam załadowaną główną klasę, która łączy się z bazą danych:

  1. class Retail_Core
  2. {
  3. public $Template, $Auth, $Database;
  4. function __construct()
  5. {
  6. try
  7. {
  8. $this->Database = new PDO('mysql:host=localhost;dbname=retail;charset=utf8', 'root', '');
  9. $this->Database->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  10. include(APP_PATH . "model/template.php");
  11. $this->Template = new Template();
  12. include(APP_PATH . "model/auth.php");
  13. $this->Auth = new Auth();
  14. }
  15. catch(PDOException $exception)
  16. {
  17. echo 'Blad polaczenia z baza danych';
  18. exit();
  19. }
  20. }
  21. }



Następnie tworzony jest obiekt

  1. $Retail = new Retail_Core();


a zaraz po nim mam zaincludowaną drugą klasę, która ma za zadanie wyciągnięcie informacji z bazy danych:

  1. class EducationTiles
  2. {
  3. function getTileTitle($round, $modal)
  4. {
  5. try
  6. {
  7. $stmt = $this->Retail->Database->prepare('SELECT title FROM education WHERE name=:name AND modal=:modal');
  8. $stmt->bindValue(':name', $round, PDO::PARAM_INT);
  9. $stmt->bindValue(':modal', $modal, PDO::PARAM_INT);
  10. $stmt->execute();
  11. return $stmt->fetch(PDO::FETCH_ASSOC);
  12. $stmt->closeCursor();
  13. unset($stmt);
  14. }
  15. catch(PDOException $exception)
  16. {
  17. echo 'Blad polaczenia z baza danych';
  18. exit();
  19. }
  20. }
  21. }


Niestety w linii gdzie przygotowywane jest zapytanie (linia nr 7) dostaję błędy:
Notice: Undefined property: EducationTiles::$Retail
Notice: Trying to get property of non-object
Fatal error: Call to a member function prepare() on null


Będę wdzięczny za podpowiedź jak to poprawnie wykonać by śmigało tiredsmiley.gif
Wazniak96
Nie zachowujesz w klasach zasady chermetyzacji danych(i pewnie innych z resztą tez ale się nie przyglądalem). Poczytaj o pradygmatach programowania obiektowego oraz o setterach i getterach. To tak z podstawowych pojęć. wink.gif
viking
$this->retail odnosi się do nulla bo nigdzie nie ma definicji ani wskazania czym to ma być. Poza tym za dużo tego wszystkiego. Jak już to coś w stylu:
  1. class Retail_Core {
  2. protected $database;
  3. protected $template;
  4.  
  5. public function setTemplate(TemplateInterface $template) {
  6. $this->template = $template;
  7. }


Ale powinieneś dążyć do minimalizmu. Zobacz sobie przykłady aplikacji zendowych https://github.com/zendframework/zf3-web, https://github.com/zf3buch/zendframework-ce...e/chapter_18_01 np jak wygląda fabryka kontrolera https://github.com/zf3buch/zendframework-ce...llerFactory.php Do kontrolera wstrzykiwane są tylko minimalne zależności.
Kmaciek
Dzięki za rady, poczytałem trochę o hermetyzacji, getterach, setterach i ogólnie o wzorcu projektowym jakim jest fabryka. Starałem się wyciągnąć patrząc na kod aplikacji zendowskich, ale niestety na tą chwilę dla mnie to czarna magia facepalmxd.gif

Jeżeli dobrze zrozumiałem to powinno się dążyć do tego, żeby atrybuty w klasach nie były publiczne, a jedynie żeby istniała możliwość ich ustawiania czy pobierania poprzez wspomniane gettery i settery. Natomiast co do samego kontrolera, powinien on sterować tym co ma się zadziać, a nie tak jak w moim przypadku nawiązywać już połączenie z bazą danych. Jeżeli moje rozumowanie jest błędne będę wdzięczny za naprowadzenie.

Idąc tym tropem zmodyfikowałem moje klasy tak, że wyglądają one następująco:

1. Sam kontroler tworzy niezbędne klasy, a połączenie z bazą danych zostało przeniesione do nowej klasy. Dodana została metoda do pobierania połączenia z bazą.

  1. class Retail_Core
  2. {
  3. protected $Template, $Auth, $Database;
  4. function __construct()
  5. {
  6. $this->setClass('Template');
  7. $this->setClass('Auth');
  8. $this->setClass('Database');
  9. }
  10. private function setClass($class)
  11. {
  12. $this->$class = new $class();
  13. }
  14. public function getDatabase()
  15. {
  16. return $this->Database->getDatabase();
  17. }
  18. }


2. Wspomniana klasa "Database" wygląda na tą chwilę następująco:

  1. class Database
  2. {
  3. protected $Connect;
  4. function __construct()
  5. {
  6. try
  7. {
  8. $this->Connect = new PDO('mysql:host=localhost;dbname=retail;charset=utf8', 'root', '');
  9. $this->Connect->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  10. }
  11. catch(PDOException $exception)
  12. {
  13. echo 'Blad polaczenia z baza danych';
  14. exit();
  15. }
  16. }
  17. public function getDatabase()
  18. {
  19. return $this->Connect;
  20. }
  21. }


3. Wszystko zostało poprzedzone autoloaderem:

  1. function __autoload($className)
  2. {
  3. require(APP_PATH.'model/'.$className.'.php');
  4. }


Przyznam się, że trochę się w tym jeszcze gubię i dalej nie wiem w jaki sposób wykorzystać w innej klasie wspomniane połączenie z bazą danych. Oczywiście siedzę dalej nad lekturą w postaci internetu, ale wszelki wskazówki będą mile widziane rolleyes.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.