Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Referencje do obiektu
Skie
post
Post #1





Grupa: Zarejestrowani
Postów: 555
Pomógł: 84
Dołączył: 20.02.2008
Skąd: Małopolska

Ostrzeżenie: (0%)
-----


Witam,
mam problem z referencjami , z którymi nie mogę sobie poradzć (PHP 5.4).
Napisałem sobie klasę cache'ującą, która zbiera referencje do pewnych obiektów i trzyma je w odpowiedniej strukturze.
W przypadku, gdy pojawiają się w niej referencje do tego samego obiektu zaczynają się schodki, które wydają się być błędem związanym z PHP niż z moją klasą.

Zobrazuję to w poniższym przykładzie.
  1. $man = new StashManager();
  2.  
  3. $obj = new StdClass;
  4. $obj -> id = 1;
  5. $obj -> x = 5;
  6. $obj -> y = 5;
  7. $man -> InsertInto("key1", $obj); // zapisuje w kontenerze pod kluczem key1 referencję do obiektu1
  8. $man -> InsertInto("key2", $obj); // zapisuje w kontenerze pod kluczem key2 referencje do obiektu1
  9. unset($obj); // czyszczę zmienną
  10.  
  11. $obj = &$man -> Select("key2"); // pobieram referencję do obiektu1


I teraz tak , jeżęli zmienię jakaś składową, np:
  1. $obj -> x = 10;


Po czym wyświetlę stan kontenera - obiekt key1 i key2 mają x ustawione na 10 - w końcu to ten sam obiekt.
Teraz chcę zamiast tego usunąć zawartość tej refrencji, robię więc:
  1. $obj = null;


Odczytuje dane i.... Tylko obietk spod key2 jest nullem. Obiekt spod key1 został niezmieniony.


Problemem okazuje się być funkcja pobierająca miejsce, wk tórym ma być wpisany obiekt.
Gdy wpisuję do kontenera ręcznie wartość:
  1. $this -> stash[...] = &$obj;


Wszystko działa w porządku. Jednak, gdy robię to pobierająć dokładne miejsce w kontenerze za pomocą funkcji:
  1.  
  2. public function &GetPlace($path, $breakOnError = false, $offset = 0) {
  3. $arr = explode('/',$path);
  4. $place = &$this -> stash;
  5. $limit = count($arr);
  6.  
  7. $i = 0;
  8. foreach ($arr as $el) {
  9. if ($i-$offset >= $limit) { break; }
  10.  
  11. if (($child = &$this -> GetChild($place, $el)) === null) {
  12. if ($breakOnError) { $empty = null; return $empty; } else { $obj = array(); $this -> SetChild($place, $el, $obj); unset($obj); }
  13. }
  14. $place = &$this -> GetChild($place, $el);
  15.  
  16. $i++;
  17. }
  18.  
  19. return $place;
  20. }
  21.  
  22. public function &GetChild(&$place, $el) {
  23. if (is_array($place) && isset($place[$el])) {
  24. return $place[$el];
  25. } else if (is_object($place) && isset($place -> $el)) {
  26. return $place -> $el;
  27. } else {
  28. $empty = null;
  29. return $empty;
  30. }
  31. }


Co robię źle?

Co robię źle?

Ten post edytował Skie 21.10.2013, 23:44:24
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
Skie
post
Post #2





Grupa: Zarejestrowani
Postów: 555
Pomógł: 84
Dołączył: 20.02.2008
Skąd: Małopolska

Ostrzeżenie: (0%)
-----


1. Identyfikator obiektu != referencja obiektu.
3. i 4. Widać, że nie do końca dobrze wytłumaczyłem problem, gdyż nie do końca o to mi chodzi.

Czytałem o Weakref, jest to ciekawa rzecz, ale nie do końca jestem do niej przekonany, gdyż jest to pewna abstrakcja nie pozwalająca na manipulację pamięcią a la C++ cz Assembler, tylko jakby to nazwać... brak oznaczenia, że dany fragment pamięci jest chroniony od strony kodu? Nie wiem jak to lepiej ująć. Boję się, że coś takiego może doprowadzić do zaistnienia dziur w systemie.

W każdym razie, zmieniłem ciut założenia. Select() i InsertInto() będą od tej chwili klonowały wczytany obiekt, a problematykę istnienia wielu kluczy do jednego obiektu rozwiążę dodając mały mechanizm tworzenia w klasie linków symbolicznych, gdzie jeden klucz nie ma wartości, tylko "wskazuje" na inny klucz. Select() , Delete() i Truncate() pozostaną bez zmian.

Minusem tego rozwiązania jest brak kompatybilności wstecznej względem starego systemu, za co pozostali deweloperzy pewnie mnie powieszą, ale... nie da się tego zrobić w PHP tak by działało w 100% po staremu. A myślę, że w parę dni, doprowadzimy system do używalności z tą klasą, bo zmiany są minimalne.

Lecą plusy za owocną konwersacje i propozycje. Dzięki.

Ten post edytował Skie 23.10.2013, 00:14:34
Go to the top of the page
+Quote Post

Posty w temacie


Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 14.10.2025 - 19:39