Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [referencje] Przesyłanie referencji zmiennej przez obiekt
Forum PHP.pl > Forum > PHP > Object-oriented programming
mrc
Cześć. Mam pewien duży problem, który spłaszczyłem do małego przykładziku. Oto kod:
  1. <?php
  2. ini_set('display_errors', 1);
  3.  
  4. class A
  5. {
  6. protected $a = array();
  7.  
  8. public function &getA()
  9. {
  10. return $this->a;
  11. }
  12.  
  13. public function setA(&$value)
  14. {
  15. $this->a = $value;
  16. }
  17. }
  18.  
  19. $arr = array('a' => 10);
  20. $a = new A();
  21. $a->setA($arr);
  22. $brr = $a->getA();
  23. $brr['a'] = 20;
  24. die(var_dump($arr));
  25. ?>


Moje oczekiwania: zmienna bbr w rezultacie wskazuje na zmienną arr i po zmianie wartości powinna zmienić się wartość w zmiennej arr.

Moje badania: zmienna arr nie zmieniła się.

Czy możecie mi powiedzieć dlaczego tak się dzieje, ew. poprawić mój kod tak aby przykład powyżej działał tak jak tego oczekuję? smile.gif
YourFrog
Poniższe działa. Chyba zwykłe przypisywanie "=" powoduje utratę "referencji". Nie jak w normalnym języku deskopowym że jak masz pointera to masz pointera.

  1. <?php
  2. ini_set('display_errors', 1);
  3.  
  4. class A
  5. {
  6. protected $a = array();
  7.  
  8. public function &getA()
  9. {
  10. return $this->a;
  11. }
  12.  
  13. public function setA(&$value)
  14. {
  15. $this->a =& $value;
  16. }
  17. }
  18.  
  19. $arr = array('a' => 10);
  20. $a = new A();
  21. $a->setA($arr);
  22. $brr =& $a->getA();
  23. $brr['a'] = 20;
  24. die(var_dump($arr));


@Down
Masz rację mój błąd z tymi pointerami.
em1X
Przypisywanie przez referencję to nie żaden wskaźnik. "Nie znam się to się wypowiem"? Po więcej informacji należy studiować oficjalną stronę języka http://www.php.net/manual/en/language.references.php.

Ps. mrc, po co w ogóle tak kombinujesz? Jest takie powiedzenie, "you are doing it wrong", i myślę, że ma tutaj zastosowanie.
mrc
Cytat
Ps. mrc, po co w ogóle tak kombinujesz?


Chciałem zrobić trait Property, którego używałaby klasa Session. Chodzi o to, by wszystko co zmienimy za pomocą obiektu Session było zmienione również w $_SESSION.

Dzięki za pomoc, wieczorem wypróbuję kod i napiszę jakie rezultaty smile.gif
em1X
  1. class Session
  2. {
  3. protected $collection=array();
  4.  
  5. public function __set($key, $value)
  6. {
  7. $this->collection[$key] = $value;
  8. $_SESSION[$key] = $value;
  9. }
  10.  
  11. public function __get($key)
  12. {
  13. if (! isset($this->collection[$key])) {
  14. throw new InvalidArgumentException(sprintf('Klucz % nie został zarejestrowany w sesji', $key));
  15. }
  16.  
  17. return $this->collection[$key];
  18. }
  19. }
  20.  
  21. $session=new Session();
  22. $session->userId=1;
  23.  
  24. var_dump($session->userId == $_SESSION['userId']);
  25.  


bez kombinowania i wymyślania.
mrc
Niestety, nie jest to po mojej myśli. Trait musi być uniwersalny, niezależny od tego, jaką tablicę dostanie (zwykłą, $_POST, $_GET, $_SESSION itp).
Tak jak napisałem wcześniej, mój problem spłaszczyłem do drobnego przykładu. W rzeczywistości odnosi się on do niejednej klasy mojego frameworka, które wymagają tej samej funkcjonalności.

Kod działa smile.gif Dzięki! smile.gif
sazian
możesz jeszcze spróbować jeszcze czegoś takiego
  1. class A implements ArrayAccess
  2. {
  3. private $a;
  4. public function setA(&$value)
  5. {
  6. $this->a = &$value;
  7. }
  8. public function offsetExists ( $offset )
  9. {
  10. return isset($this->a[$offset]);
  11. }
  12. public function offsetGet ( $offset )
  13. {
  14. return isset($this->a[$offset]) ? $this->a[$offset] : null;
  15. }
  16. public function offsetSet ( $offset , $value )
  17. {
  18. if (is_null($offset))
  19. {
  20. $this->a[] = $value;
  21. }
  22. else
  23. {
  24. $this->a[$offset] = $value;
  25. }
  26. }
  27. public function offsetUnset ( $offset )
  28. {
  29. unset($this->a[$offset]);
  30. }
  31.  
  32.  
  33. }
  34. $a = new A();
  35. $a->setA($_SESSION);
  36. $a['x']=1;
  37. $_SESSION['y']=2;

zadziała z każdą tablicą
em1X
Cytat(sazian @ 16.01.2014, 23:06:57 ) *
możesz jeszcze spróbować jeszcze czegoś takiego


Temat jest wyczerpany, czemu męczysz?
mrc
Cytat(sazian @ 16.01.2014, 23:06:57 ) *
możesz jeszcze spróbować jeszcze czegoś takiego


Właściwie to coś podobnego mam we frameworku, tylko bardziej rozbudowane smile.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.