Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Klasy + dziedziczenie + referencja zmiennych
Forum PHP.pl > Forum > PHP
sniffer
Witam,
posiadam 3 klasy:
  1. <?php
  2.  
  3. class MainData
  4. {
  5. //class pointers
  6. var $_db = null;;
  7. var $_cache = null;
  8. var $_connection = null;
  9. //(...)
  10.  
  11. function MainData() {}
  12.  
  13. function &GetInstance()
  14. {
  15. static $instance;
  16. if(!isset($instance))
  17. {
  18.  $instance = new MainData();
  19. }
  20. return $instance;
  21. }
  22. }
  23.  
  24. class MainSingletonReference extends MainData
  25. {
  26. //class pointers
  27. var $_db;
  28. var $_cache;
  29. var $_connection;
  30. //(...)
  31.  
  32. function MainSingletonReference()
  33. {
  34. static $instance;
  35. if(!isset($instance))
  36. {
  37. $instance =& MainData::GetInstance();
  38. }
  39.  
  40. foreach (get_class_vars(get_class($instance)) as $var => $value)
  41. {
  42. $this->$var =& $instance->$var;
  43. }
  44. }
  45. }
  46.  
  47. class Main extends MainSingletonReference
  48. {
  49. function Main()
  50. {
  51. global $db;
  52. parent::MainSingletonReference();
  53. $this->_db =& $db; //wszystko ok
  54. echo $this->_db; //prawidłowo, zwraca "Object"
  55. $maindata =& MainData::GetInstance();
  56. echo $maindata->_db; //i tu jest problem... powinno zwrócić również Object, ale tak się nie dzieje :/
  57. }
  58. //(...)
  59. }
  60.  
  61. ?>


czy ktoś może wie gdzie jest błąd i jak to naprawić? ogólny pomysł był taki, żeby zmienne z klasy MainData były dostępne w innych klasach, ale żeby klasa MainData była singletonem, czyli, żeby zmienne nie były dublowane, a zmiana zmiennej klasie dziedziczącej powodowała zmianę w klasie MainData za pośrednictwem referencji w klasie MainSingletonReference, niestety tak się nie dzieje i zmienne z klasy MainData nie są zmieniane...

testowałem to pod php 4.4.0 i Win2k

ktoś ma jakieś pomysły?
z góry dzięki...
DeyV
php pro -> php
dr_bonzo
  1. <?php
  2. echo $maindata->_db; //i tu jest problem... powinno zwrócić również Object, ale tak się nie dzieje :/
  3. ?>

Ale nigdzie nie ustawiasz wartosci _db, wiec wyswietla ci NULLa (daj var_dump zamiast echo; //class pointers var $_db = null;)

Sprawdzane na php 5.0/win
sniffer
no ok, faktycznie var_dump daje NULL'a, ale nie zgodze się, że zmienna _db z klasy MainData nie jest ustawiana...
otóż w funkcji MainSingletonReference() tworzona jest referencjia do odpowiadającej zmiennej z klasy MainData
  1. <?php
  2.  
  3. foreach (get_class_vars(get_class($instance)) as $var => $value)
  4. {
  5. $this->$var =& $instance->$var;
  6. }
  7.  
  8. class Main extends MainSingletonReference
  9. {
  10. function Main()
  11. {
  12. global $db; // <- wartość ustawiona przed inicjalizacją klas !!
  13. parent::MainSingletonReference(); // <- zainicjowanie referencji, także zmienna $this->_db klasy MainSingletonReference powinna zapisać dane do $_db z klasy MainDat
    a poprzez referencjię
  14. $this->_db =& $db; //ustawienie wartości
  15. echo $this->_db; //prawidłowo, zwraca "Object"
  16. $maindata =& MainData::GetInstance();
  17. echo $maindata->_db; //powinno być równe $this->_db ustawione wcześniej
  18. }
  19. }
  20.  
  21. ?>

można prosić o sprostowanie gdzie tutaj jest błąd, wygląda na to, że nie działa przesyłanie przez referencjię w klasie MainSingletonReference ... nie jestem pewien ale chyba ustawienie $this->_db w klasie Main nadpisuje referencję...
może lepszym rozwiązaniem było by zaimplementowanie destruktora za pomocą register_shutdown_function() i tam dopiero zmienić wartości zmiennych klasy MainData odpowiednio je nadpisując zmiennymi z klasy dziediczącej...

co o tym sądzicie? czy się myle? czy jednak da się to zrobić za pomocą konstruktora? jeśli tak, to gdzie czai się ten błąd?questionmark.gifquestionmark.gifquestionmark.gif?
dr_bonzo
  1. <?php
  2.  
  3. class MainData
  4. {
  5. //class pointers
  6. var $_db = null;
  7. var $_cache = null;
  8. var $_connection = null;
  9. //(...)
  10.  
  11. function MainData() {}
  12.  
  13. function &GetInstance()
  14. {
  15. static $instance;
  16. if(!isset($instance))
  17. {
  18.  $instance = new MainData();
  19. }
  20. return $instance;
  21. }
  22. }
  23.  
  24. class MainSingletonReference extends MainData
  25. {
  26. //class pointers
  27. var $_db;
  28. var $_cache;
  29. var $_connection;
  30. //(...)
  31.  
  32. function MainSingletonReference()
  33. {
  34. static $instance;
  35. if(!isset($instance))
  36. {
  37. // 1sza instancja, _db bedzie rowne NULL
  38. $instance =& MainData::GetInstance();
  39. // object #3
  40. var_dump( $instance );
  41. }
  42.  
  43. foreach (get_class_vars(get_class($instance)) as $var => $value)
  44. {
  45. $this->$var =& $instance->$var;
  46. //var_dump( $this->$var );
  47. // $this->_db =& $instance->_$db (tu: NULL), co pokazuje ^^ var_dump
  48. }
  49. }
  50. }
  51.  
  52. class Main extends MainSingletonReference
  53. {
  54. function Main()
  55. {
  56. global $db;
  57. parent::MainSingletonReference();
  58.  
  59. $this->_db =& $db; //wszystko ok !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  60. // TU tworzysz obiekt klasy Main (jestesmy w konstruktorze), ktoremu _przepisujesz_ wlasciwosci (properties/pola)
  61. // z instancji (singletona) klasy MainData (w wywolaniu parent::MainSingletonReference(); ).
  62. // Co oznacza ze masz juz DWA obiekty: jeden klasy Main, a drugi jest 
  63. // singletonem MainData ($instance -- MainSingletonReference)
  64. // $this->_db =& $db; modyfikuje ci obiekt klasy MAIN, a singleton MainSingletonReference po
    zostaje
  65. // bez zmian
  66. // wiec $maindata =& MainData::GetInstance(); zwroci ci tego singletona nie zmodyfikowagego
  67. // odkomentowane var_dumpy to pokazuja
  68.  
  69. // echo $this->_db; //prawidłowo, zwraca "Object" : [OK]
  70. $maindata =& MainData::GetInstance();
  71. // echo $maindata->_db; //i tu jest problem... powinno zwrócić również Object, ale tak się nie dzieje :/
  72. }
  73. //(...)
  74. }
  75.  
  76. class XXX
  77. {
  78. }
  79. $db = new XXX();
  80.  
  81. $x = new Main();
  82. // object #2
  83. var_dump( $x );
  84. ?>
sniffer
Witam,
mam byka:
1.
  1. <?php
  2.  
  3. class MainSingletonReference extends MainData
  4.  
  5. ?>

powinno być
  1. <?php
  2.  
  3. class MainSingletonReference
  4.  
  5. ?>

2.
  1. <?php
  2.  
  3. class Main extends MainSingletonReference
  4. {
  5. function Main()
  6. {
  7. global $db;
  8. parent::MainSingletonReference();
  9.  
  10. $this->_db =& $db;
  11. }
  12. }
  13.  
  14. ?>

powinno być:
  1. <?php
  2.  
  3. class Main extends MainSingletonReference
  4. {
  5. function Main()
  6. {
  7. global $db;
  8. parent::MainSingletonReference();
  9.  
  10. $this->_db = $db;
  11. }
  12. }
  13.  
  14. ?>

[bez referencji przy przypisywaniu $db] no i właśnie może ktoś mi powie, dlaczego tak się dzieje? dlaczego nie moge tak przypisać tutaj tej zmiennej.... potrzebuje takie rozwiązanie, ponieważ zmienne z klasy MainData mają przechowywać pointery do klas z singletonem, i tu przypisanie przez referencję jest niezbędne....
Jak to obejść?questionmark.gif

Z góry 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.