Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Zwracanie przez referencję
Forum PHP.pl > Forum > PHP > Object-oriented programming
varez
Witam,
potrzebuję, żeby moja statyczna metoda zwracała referencję do statycznego atrybutu, który jest tablicą, a konkretnie elementu tablicy, który znowu jest obiektem innej klasy. Obiekt ten chcę usunąć, wywołując destruktor. Tyle wstępu, teraz trochę kodu:

  1. <?php
  2. class wykobot {
  3. static private $channels=array();
  4.  
  5. static public function zmyslona_funckja() {
  6. self::$channels[] = array('name'=>'wtest', 'obj'=>new channel());
  7. }
  8. static public function &getChannelByName($name) {
  9. foreach (self::$channels as &$channel) {
  10. if ($channel['name']==$name) {
  11. return $channel['obj'];
  12. }
  13. }
  14. return false;
  15. }
  16. }
  17.  
  18. class channel {
  19. public function __destruct() {
  20. die('destruktor!');
  21. }
  22. }
  23.  
  24. wykobot::zmyslona_funckja();
  25. $ch = &wykobot::getChannelByName('wtest'); // element tablicy jest zwrócony, ale nie jako referencja
  26. unset($ch);
  27. die('koniec!')
  28. ?>


Niby obiekty zwracane są zawsze jako referencje, ale w wersji bez "&" też nie podziała, dlatego na próbę dopisałem.
Wiem też, że nie przeszadza to, że atrybut wykobot::$channels jest prywatny, ma tak działać.
Jeżeli w wykobot::getChannelByName przed returnem wstawimy unset($channel['obj']) to podziała jak trzeba, tj jedyny output jaki dostaniemy to "destruktor!".
-=Peter=-
Obiekty zawsze są zwracana i przekazywane jako parametry przez referencję. Funkcja unset usuwa referencję do zmiennej, nie samą zmienną. Zmienna zostanie usunięta przez gc gdy wszystkie referencje do danej zmiennej zostaną usunięte lub wypadną poza zakres. Zrób sobie metodę wykobot::removeChannel($name).
varez
to jak to zrobic zeby bylo dobrze?
removeChannel mnie nie ratuje, bo ja potrzebuje tego obiektu właśnie, bo będzie na nim sporo operacji, unset był tylko dla testu, że posiadam faktycznie obiekt pod tą zmienną, a nie jakąś jego kopię czy coś.
Noidea
Nie będziesz miał żadnej kopii. Obiekty w PHP5 przekazywane są przez referencje i nie potrzeba do tego żadnych &
  1. <pre>
  2. <?php
  3.  
  4. class A
  5. {
  6. private $arr = array();
  7.  
  8. public function __construct()
  9. {
  10. $this->arr['obj'] = new B();
  11. }
  12.  
  13. public function getObj()
  14. {
  15. return $this->arr['obj'];
  16. }
  17.  
  18. public function showObj()
  19. {
  20. echo $this->arr['obj']->var . "\n";
  21. }
  22. }
  23.  
  24. class B
  25. {
  26. public $var = 1;
  27. }
  28.  
  29.  
  30. $a = new A();
  31. $a->showObj();
  32.  
  33. $thisIsNotACopy = $a->getObj();
  34. $thisIsNotACopy->var = 5;
  35. unset( $thisIsNotACopy );
  36.  
  37. $a->showObj();
  38.  
  39. $thisIsCopy = clone $a->getObj();
  40. $thisIsCopy->var = 10;
  41. unset( $thisIsCopy );
  42.  
  43. $a->showObj();
  44.  
  45. ?>
  46. </pre>
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.