Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Destruktor traci bibliotekę
Marcstee
post
Post #1





Grupa: Nieautoryzowani
Postów: 42
Pomógł: 0
Dołączył: 15.12.2009

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


Witam.

Mam pewien problem z destruktorem. Problem wygląda następująco:

Wywołuje się front_controller i w nim są ładowane klasy z biblioteki. Potem akcja rozgrywa się w modelu. Tam wszystko pięknie działa wszystkie klasy są dostępne. Potem tworzę w nim nowy obiekt klasy X. wywołuję funkcję publiczną tego obiektu i kończę akcje. W destruktorze klasy X jest wykonywana pewna funkcja która wymaga innych klas z biblioteki. Jednak destruktor ten już ich nie widzi. Metoda wywoływana na tym obiekcie może być nawet pusta a i tak straci się biblioteka (ale tylko w obrębie tej klasy). Gdy po prostu stworze obiekt klasy X i nie wywołam na nim żadnej metody to w destruktorze dalej dostępne są klasy z biblioteki.

Na prawdę nie wiem jaki może być tego powód. Bardzo proszę o jakieś porady.
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 14)
wookieb
post
Post #2





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




A mógłbyś sypnąć trochę kodem ponieważ trudno Cię do końca zrozumieć albo ja dziś jestem zaćmiony.
Go to the top of the page
+Quote Post
Marcstee
post
Post #3





Grupa: Nieautoryzowani
Postów: 42
Pomógł: 0
Dołączył: 15.12.2009

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


wchodzimy na stronę -> wywoływany jest front_controller w którym ładowana jest cała biblioteka (require_once).
dalej akcja przekazywana jest do modelu. W modelu są różne akcje. Jedna z nich to:
  1. ...
  2. $obiektX = new xclass();
  3. ...

W obiekcie X w destruktorze jest pewna akcja:
  1. ...
  2. function __destruct(){
  3. klasaZBiblioteki::jakasFunkcjaStatycznaNaPrzyklad();
  4. }
  5. ...

Jeżeli nie wywołam na $obiektX żadnej metody tej klasy to jest wszystko ok i działa. Jednak gdy użyje jakieś:
  1. ...
  2. $obiektX->doSomething();
  3. ...

To destruktor już nie zadziała prawidłowo bo nie będzie widział już 'klasaZBiblioteki'.
Go to the top of the page
+Quote Post
wookieb
post
Post #4





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




Ok. Czyli dostajesz błąd że nie ma klasy "klasaZBiblioteki" tak?
Opowiedz jeszcze jaki masz proces autoładowania klas, czyli jak wygląda twój __autoload.
Jak narazie wydaje mi sie, że albo akcja wywołuje zmiane katalogu roboczego (chdir) albo include_path (set_include_path), co może powodować właśnie taki problem.
Albo jeżeli to php 5.3 to zmieniany jest namespace

Ten post edytował wookieb 18.05.2010, 13:45:01
Go to the top of the page
+Quote Post
Marcstee
post
Post #5





Grupa: Nieautoryzowani
Postów: 42
Pomógł: 0
Dołączył: 15.12.2009

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


autoload jedzie po calym lib'ie i ładuje wszystkie klasy pokolei.
a akcja doSomething() może być nawet pusta (samo return true) a i tak ten sam problem będzie.
PHP5.2.11
to po prostu wygląda tak, jakby obiektX jeżeli wywołuje się na nim jakaś metoda to usuwa się na samym końcu po bibliotece. A gdy nie użyje się niczego na nim, że usuwa się pierwszy kiedy jeszcze wszystko jest
Go to the top of the page
+Quote Post
wookieb
post
Post #6





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




Pokaż kod swojej xclass oraz podaj komunikat błędu jaki otrzymujesz.

Ten post edytował wookieb 18.05.2010, 14:05:01
Go to the top of the page
+Quote Post
Marcstee
post
Post #7





Grupa: Nieautoryzowani
Postów: 42
Pomógł: 0
Dołączył: 15.12.2009

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


Ta xclass to moze byc nawet samo:
  1. class xclass
  2. {
  3. function __destruct(){
  4. klasaZBiblioteki::jakasFunkcjaStatycznaNaPrzyklad();
  5. }
  6. public function doSomething() {
  7. }
  8. }

a mimo to będzie błąd. A błąd jest, że nie może załadować odpowiedniej klasy.
Go to the top of the page
+Quote Post
wookieb
post
Post #8





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




Czy błąd nadal będzie występować jak zrobisz coś takiego pod koniec skryptu?
  1. $twoj_obiekt_xclass->__destruct();
  2. unset($twoj_obiekt_xclass);


Jeżeli tak będzie problem rozwiązęsz jeżeli dołączysz potrzebną bibliotekę na samym początku pliku definiującego podaną klasę.

Ten post edytował wookieb 18.05.2010, 16:11:55
Go to the top of the page
+Quote Post
Marcstee
post
Post #9





Grupa: Nieautoryzowani
Postów: 42
Pomógł: 0
Dołączył: 15.12.2009

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


No tak, jak dołączę ją w pliku xclassy to działa. Ale chciałbym wiedzieć dlaczego? Co powoduje, biblioteka się nagle traci?
Go to the top of the page
+Quote Post
wookieb
post
Post #10





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




Na zakończenie skryptu wywoływane są wszystkie destruktory istniejących obiektów, co powoduje też zmianę katalogu roboczego. Dlatego twój autoloader nie był w stanie znaleźć potrzebnej klasy.
Go to the top of the page
+Quote Post
Marcstee
post
Post #11





Grupa: Nieautoryzowani
Postów: 42
Pomógł: 0
Dołączył: 15.12.2009

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


Mhm ale to nie tłumaczy jednej rzeczy. Dlaczego gdy nie wywołam metody doSomething() to destruktor znajduje odpowiednią klasę?
Go to the top of the page
+Quote Post
wookieb
post
Post #12





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




Nie wiem dlaczego używam php 5.3.2 a tam jest lepszy GC, wiec moze to wynikac z wersji php. Po prostu gc mógł uznać, że obiekt będzie ci niepotrzebny wcześniej i destruktor wykonał się wcześniej.

Ten post edytował wookieb 18.05.2010, 18:09:04
Go to the top of the page
+Quote Post
Marcstee
post
Post #13





Grupa: Nieautoryzowani
Postów: 42
Pomógł: 0
Dołączył: 15.12.2009

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


Mhm... czyli należy przypuszczać, że skoro z obiektem nic się nie robi będzie on wcześniej usunięty, niż jakby były na nim wykonywane operacje. Ok. A czy są może jakieś źródła gdzie można by poszerzyć wiedzę na ten temat? Bo myślę, że warto się tym zainteresować a nie mam pojęcia jak tego poszukać.
Go to the top of the page
+Quote Post
wookieb
post
Post #14





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




Szczerze mówiąc to nie wiem dokładnie gdzie znajdziesz to o czym rozmawiamy ale poczytałbym tutaj
http://pl.php.net/manual/en/features.gc.php

Oraz ciekawostka
http://paul-m-jones.com/archives/262
Go to the top of the page
+Quote Post
Marcstee
post
Post #15





Grupa: Nieautoryzowani
Postów: 42
Pomógł: 0
Dołączył: 15.12.2009

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


Hmmm ciekawy temat powiem. Zrobilem kilka testów i oto wyniki:
  1. <?php
  2. class Foo
  3. {
  4. public $var = 'xxsdcadscadscasdcsdcasdcasx';
  5.  
  6. public function foo_function(){}
  7. }
  8.  
  9.  
  10. $foo = new Foo();
  11. $foo->foo_function();
  12.  
  13. unset ($foo);
  14.  
  15. ?>


gdy odpalimy ten plik wynik będzie (u mnie) taki:
  1. 87048
  2. 87368
  3. 87136


gdy jednak zakomentujemy $foo->foo_function();
to wynik już będzie taki:
  1. 86784
  2. 87016
  3. 86784


Ciekawe jest to, że w 1 wypadku pamieć jak widać nie do końca została zwolniona. Test wykonany w PHP 5.2.11. Wersja 5.3.0 już zwalnia całkowicie pamięć.

Natomiast co do omawianego problemu to nie znalazłem jednoznacznej odpowiedzi, jednak wydaje mi się ( w oparciu o to co przeczytałem), że jest to spowodowane tym, że jak obiekt jest stworzony ale nie używany w żaden sposób to jest on szybciej likwidowany. Gdy jednak coś z nim robimy PHP czeka do samego końca bo może jeszcze coś z nim się stać i dlatego był kasowany później co powodowało te problemy.
Go to the top of the page
+Quote Post

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

 



RSS Aktualny czas: 24.08.2025 - 17:21