Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] Zastosowanie getInstance
Forum PHP.pl > Forum > Przedszkole
rasgan
Witam, napisałem sobie klasę SQL do obsługi bazy. Nic nadzwyczajnego. Mam też dwie inne klasy: Extenstion (ładuje mi klasy rozszerzeń) i klasę Auth (klasa z autoryzacja uzytkownika). Na czym polega problem? Nie umiem się w klasie Auth odwołać do bazy danych. Podam kod i może będzie jaśniej:

Część kalsy SQL
  1. <?php
  2. public static function init( $host, $user, $pass, $dbname, $p = false )
  3. {
  4. if ( !self::$instance instanceof self )
  5. {
  6. self::$instance = new Wolf_MySQL_DBE( $host, $user, $pass, $dbname, $p = false );
  7. }
  8. return self::$instance;
  9. }
  10. ?>


Klasa extension
  1. <?php
  2. class Extension
  3. {
  4. public $db;
  5. public $auth;
  6.  
  7. public function __construct()
  8. {
  9. $this->db = SQL::init( 'localhost', 'root', '', 'test', false );
  10. $this->auth = AUTH::init();
  11. }
  12. }
  13. ?>


i klasa AUTH (jej część)
  1. <?php
  2. class AUTH extends Extension {
  3. private static $instance;
  4.  
  5. public static function init()
  6. {
  7. if ( !self::$instance instanceof self )
  8. {
  9. self::$instance = new AUTH();
  10. }
  11. return self::$instance;
  12. }
  13. function login( $login, $pass )
  14. {
  15. echo "<p>------------------------------------------------------</p>";
  16.  
  17. echo "<p>------------------------------------------------------</p>";
  18. }
  19. }
  20. ?>


Nie wiem w jaki sposób odwołać sie w metodzie login do bazy danych. Próbowałem poprzez $this->db->setSql(), przez $db->setSql(), setSql i nic, dostaję komunikat
Kod
Call to a member function set_sql() on a non-object inobject


Co robię źle? Widziałem podobny mechanizm u kumpla, ale on siedzi w wojsku i nie ma mi jak wyjaśnić co zrobił :/
__mK
parent::NazwaFunkcjiRodzica albo Extension::NazwaFunkcjiRodzica

ale tutaj nie widze czegos takiego jak: set_sql()
rasgan
Nie ma setSql bo nie wkleiłem smile.gif Musiałbym całą klasę SQL wkleić smile.gif

dam jeszcze raz co mam i co chcę osiągnąć:
  1. <?php
  2. class SQL
  3. {
  4. function init()
  5. { utworzenie instancji klasy SQL }
  6. function setSql()
  7. { }
  8. }
  9.  
  10. class Auth extends Extension
  11. {
  12. function init()
  13. { utworzenie instancji klasy auth }
  14. function login()
  15. {
  16.  //tutaj chciałbym by można było korzystać z metod klasy SQL w taki sposób
  17. $this->db->setSQL();
  18. }
  19. }
  20.  
  21. class Extension
  22. {
  23. public $db;
  24. public $auth;
  25.  
  26. public function __construct()
  27. {
  28. $this->db = Wolf_MySQL_DBE::init( 'localhost', 'root', '', 'test', false );
  29. $this->auth = AUTH::init();
  30. }
  31. }
  32.  
  33. // tworze obiekt na którym wykonuje moje metody
  34. $d = new Extension;
  35. $d->auth->login();
  36. $d->db->setSQL();
  37. ?>


Jak zrobić, by można było w taki sposób odwoływać się do tych rzeczy? Kumpel ma tak, że sobie utworzył jeden obiekt $strona i na nim wykonuje metody np:
  1. <?php
  2. $strona = new Extension;
  3. $strona->auth->login();
  4. if ($strona->auth->isLogged)
  5. {
  6. echo 'zalogowany';
  7. $strona->db->setSQL();
  8. echo $strona->db->getRows();
  9. }
  10. else
  11. {
  12. echo 'Zaloguj sie';
  13. }
  14. ?>


Coś takiego chciałbym osiągnąć, bo uważam, ze nieźle to działa, sprawdza się i przyzwyczaiłem się do tego, ale muszę dopisać kilka swoich rzeczy, a nie wiem jak je później wykorzystać w jego mechaniźmie. W moim własnym, też by mi się przydało coś takiego.

--------
-EDIT-
--------
Zauważyłem, że jak dam w klasie AUTH w konstruktorze linijkę
  1. <?php
  2. $this->db = SQL::getInstance();
  3. ?>
to wtedy działa idealnie, ale nie moge przecież w każdej klasie pobierać instancji każdej klasy, od tego chce mieć klasę extension w której mi to będzie robił automat.
Kicok
Ja proponuję takie rozwiązanie:
  1. <?php
  2.  
  3. class SQL
  4. {
  5.  
  6. public function __construct()
  7. {
  8. echo '<b> SQL::__construct() </b><br />';
  9. }
  10.  
  11. public function connect( $dbhost, $dbuser, $dbpass, $dbname, $persistent=true )
  12. {
  13. echo '<b> SQL::connect() </b><br />';
  14. }
  15.  
  16. public function setSQL()
  17. {
  18. echo '<b> SQL::setSQL() </b><br />';
  19. }
  20.  
  21. }
  22.  
  23.  
  24. class Auth
  25. {
  26.  
  27. public function __construct() 
  28. { 
  29. echo '<b> Auth::__construct() </b><br />';
  30. }
  31.  
  32. public function login()
  33. {
  34. echo '<b> Auth::login() </b><br />';
  35.  
  36. // Wykonujemy zapytanie
  37. $ext = new Extension();
  38. $ext->SQL->setSQL();
  39. }
  40.  
  41. }
  42.  
  43.  
  44.  
  45. class Extension
  46. {
  47. private static $objects = array();
  48.  
  49.  
  50. public function __construct() { }
  51.  
  52. public function __get( $object )
  53. {
  54. $object = strtolower( $object );
  55.  
  56.  
  57. // Sprawdzamy, czy dana klasa istnieje 
  58. // i czy jej obiekt znajduje się już w tabeli Extension::$objects
  59. // Jeśli nie, to go tworzymy
  60. if( !isset( self::$objects[$object] ) ) 
  61. {
  62. if( !class_exists( $object, true ) ) {
  63. throw new Exception( 'Class "' . htmlspecialchars( $object, ENT_QUOTES, 'UTF-8' ) . '" not exists' );
  64. }
  65.  
  66. self::$objects[$object] = new $object();
  67. }
  68.  
  69.  
  70. // Zwracamy obiekt
  71. return self::$objects[$object];
  72. }
  73.  
  74. }
  75.  
  76.  
  77.  
  78. $ext = new Extension();
  79.  
  80. // Łączymy się z bazą danych
  81. $ext->SQL->connect( 'localhost', 'root', '', 'test', false );
  82. // Wywołujemy metodę login()
  83. $ext->Auth->login();
  84.  
  85. ?>


Obiekty przechowywane są w zmiennej statycznej klasy Extension, więc nie są one gubione przy tworzeniu nowych obiektów tej klasy.
Mankamenty:
- Klasa Extension nie może mieć zmiennej publicznej o nazwie identycznej, jak nazwa którejś z twoich klas (chociaż nie wiem czy będziesz potrzebował jakiekolwiek zmienne publiczne w klasie Extension)
- Brak możliwości przekazania parametrów do konstruktora wywoływanej klasy. Można to uzyskać przez zamianę magicznej metody __get() na magiczną metodę __call(), a następnie obiekty tworzyć przy użyciu eval" title="Zobacz w manualu PHP" target="_manual - jednak takie rozwiązanie mi się osobiście nie podoba.
rasgan
Kicok, dziękuję ślicznie. Właśnie o coś takiego mi chodziło.

Ja siedziałem też nad problemem trochę w sobotę i znalazłem takie rozwiązanie:

  1. <?php
  2.  
  3. class a
  4. {
  5. public static function & getInstance()
  6. {
  7. static $instance;
  8. if ( !isset( $instance ) )
  9. {
  10. $instance = new a;
  11. }
  12. return $instance;
  13. }
  14.  
  15. public function fca()
  16. {
  17. echo 'klasa a';
  18. }
  19. }
  20.  
  21. class c extends b
  22. {
  23. public static function & getInstance()
  24. {
  25. static $instance;
  26. if ( !isset( $instance ) )
  27. {
  28. $instance = new c;
  29. }
  30. return $instance;
  31. }
  32.  
  33. public function fcc()
  34. {
  35. echo 'klasa c <br />';
  36. $this->a->fca();
  37.  
  38. }
  39. }
  40.  
  41. class b
  42. {
  43. public $c;
  44. public $a;
  45.  
  46. public static function & getInstance()
  47. {
  48. static $instance;
  49. if ( !isset( $instance ) )
  50. {
  51. $instance = new b;
  52. }
  53. return $instance;
  54. }
  55.  
  56. public function __construct()
  57. {
  58. $this->a = a::getInstance();
  59. }
  60.  
  61. public function pokaz()
  62. {
  63. echo '<pre>';
  64. print_r($this);
  65. echo '</pre>';
  66. }
  67. }
  68.  
  69. $db = c::getInstance();
  70.  
  71. /* @var $db c */
  72. $db->pokaz();
  73. $db->a->fca();
  74. $db->fcc();
  75.  
  76. ?>


------
EDIT
------

Po krótkich testach doszedłem do wniosku, że Twoje podejście jest bardziej uniwersalne od mojego. Wystarczy, że utworzę sobie swój nowy obiekt typy Extension i już mam dostęp do wszystkich rozszerzeń jakie potrzebuję. A wiesz może jak napisać by ZEND obsługiwał podpowiedzi dla takiej składni?
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.