Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: __destruct
Forum PHP.pl > Forum > PHP > Object-oriented programming
goffyy
Mam troche moze glupie pytanie ale nie dziala mi jedna rzecz i zastanawiam sie dlaczego.

Mam klase w ktorej jest zdefiniowana funkcja __destruct(). Niestety podczas konczenia wykonywania sie skryptow funkcja ta nie zostaje wywolana pomimo ze klasa o ktorej mowa zostala wykorzystana. Mam wiec pytanie czy dziala to na wszystkich wersjach php5 (o ile mi wiadomo to tak) i czy przy konczeniu programu wywoluje sie ta procedura automatyczna czy trzeba zrobic przykladowo unset($jakasklasa) - co tez u mnie nie dziala sad.gif

Z gory dzieki za podpowiedz.
nasty
tak dziala na wszystkich php5, podaj moze kod ?
goffyy
Kod jest banalny:

  1. <?php
  2. function __destruct() {
  3. if ($this->dirty) $this->save();
  4. }
  5. ?>


Kod jest o tyle prosty ze ma wywolac funkcje save() ktora ma byc uzywana do zapisywania ustawien aplikacji - jest to prosty wzorzec Registry. Z gory mowie ze funkcja save() wywolywana oddzielnie dziala poprawnie. Niestety __destruct nie uruchamia sie automatycznie. Pozostale funkcje typu __construct(), __autoload() itp dzialaja poprawnie.
nasty
a napisz echo $this->dirty...
boc cos mi tu smierdzi falsem w $this->dirty tongue.gif
goffyy
Probowalem ale nawet jak dasz jakies echo na poczatku to i tak sie nie wyswietla. Poprostu dziala tak jakby pomijal _destruct() i zastanawia mnie dlaczego sad.gif
nasty
nic nie wyswietla, bo nic niema w tej zmiennej, w destrukt, zrob $this->dirty = true a zobaczysz ze bedzie dzialac, ale to tylko zeby ci pokazac ze dziala destruktor, podaj mi caly kod to ci powiem co jest nie tak.
goffyy
Caly kod klasy:

  1. <?php
  2. class kernel_ApplicationRegistry extends kernel_Registry {
  3. private static $instance;
  4. private $freezefile = "temp/ApplicationRegistry.txt";
  5. private $values = array();
  6. private $dirty = false;
  7.  
  8. private function __construct() {
  9. $this->doReload($this);
  10. }
  11.  
  12. static function instance() {
  13. if (!self::$instance) self::$instance = new self(); 
  14. return self::$instance;
  15. }
  16.  
  17. static function reload() {
  18. self::instance()->doReload();
  19. }
  20.  
  21. private function doReload() {
  22. if (!file_exists($this->freezefile)) return false;
  23. $serialized = file_get_contents($this->freezefile, true);
  24. $array = unserialize($serialized);
  25. if (is_array($array)) {
  26. $array = array_merge($array, $this->values);
  27. $this->values = $array;
  28. return true;
  29. }
  30. return false;
  31. }
  32.  
  33. private function save() {
  34. echo "save";
  35. $frozen = serialize($this->values);
  36. try {
  37. file_put_contents($this->freezefile, $frozen, FILE_USE_INCLUDE_PATH);
  38. } catch (KernelException $e) {
  39. $e->__toString();
  40. }
  41. $this->dirty = false;
  42. }
  43.  
  44. function get($key) {
  45. return $this->values[$key];
  46. }
  47.  
  48. function set($key, $val) {
  49. echo "ustawiam";
  50. $this->dirty = true;
  51. $this->values[$key] = $val;
  52. }
  53.  
  54. function isEmpty() {
  55. return empty(self::instance()->values);
  56. }
  57.  
  58. function __destruct() {
  59. echo "wychodze";
  60. if ($this->dirty) $this->save();
  61. }
  62. }
  63. ?>


Jak cos znajdziesz to daj znac smile.gif
nasty
no pewnie ze nic nie zrobi bo nigdze nie przydzielasz jej innej wartosci niz false na poczadku, daj np, w __construct $this->dirty = true, i wykonaj, ale wydac ze zapomniales ustalic w jakiejkowiek funkcji zeby zmieniala $this->dirty na true
goffyy
Jest ustalana na true tutaj:

  1. <?php
  2. function set($key, $val) {
  3. echo "ustawiam";
  4. $this->dirty = true;
  5. $this->values[$key] = $val;
  6. }
  7. ?>


Czyli w momencie jak ustawiasz jakas nowa zmienna lub jak zmianiasz istniejaca.
nasty
jesli ta funkcje wywolujesz, to powinno dzialac, jak nie to ja juz nieiwm sad.gif
goffyy
ja tez nie wiem wlasnie sad.gif musze do admina napisac bo wyglada ze cos nie tak maja z php sad.gif
nasty
admin tu ci nic nie pomoze, nie zawracaj mu glowy tongue.gif
hwao
a ja wiem smile.gif

Dekstruktor jest generalnie zawsze wykonywany, ale jest z nim sporo problemow...

http://www.zyxist.com/pokaz.php/glupi_blad_php
O tu. smile.gif

Zeby sprawdzic czy sie wlacza zrob po prostu

  1. <?php
  2. function __destruct() {
  3. // echo nie bedzie widac, poniewaz dekstuktor
  4. // zazwyczaj jest odpalany po skonczeniu przesylania danych do klienta http (czyli nie widzi juz tego)
  5. echo "wychodze";
  6. // Zdebugujemy to tak
  7.  
  8.  
  9. [b]file_put_contents( './test.txt', 'Desktruktor, uruchomiony'.date('d.m.Y h:i:s' ) );
  10. [/b]
  11. if ($this->dirty) $this->save();
  12. }
  13. ?>
goffyy
Masz racje smile.gif Tylko ze u mnie nie dizala na razie w zaden sposob sad.gif
mariuszn3
goffyy destruktor zawsze jest odpalany i nie jest to żadne widzimisie..
Przetestowałem Twój kod i zawsze wyświetla mi 'wychodzę' więc wszystko jest ok..
Sprawdź czy jakieś inne czynniki nie wpływają na to, że tego nie widzisz.
Jest tylko jedyna mi znana możliwość aby destruktor nie był odpalony.
Tak będzie jeśli przy wyjściu aplikacji wystąpił błąd 'fatal error' podczas wywołania destruktora jednego z obiektów, wtedy żadne inne destruktory jeszcze istniejących obiektów już nie zostaną odpalone.
goffyy
teoretycznie to i ja wiem ze tak powinno byc gorzej ze na tym serwerze co testuje nie jest smile.gif
splatch
Może to głupie pytanie.. ale masz jakąś instancje tej klasy [stworzony obiekt]?
nasty
a wez w construct napisz :
  1. <?php
  2. $this->__destruct();
  3. ?>

i zobacz czy wykona ..., bo jak nie to ....
goffyy
W ten sposob dziala wszystko poprawnie a wiec to wina php jakas sad.gif
Cysiaczek
Możesz pokazac klasę bazową?
goffyy
To jest prosta klasa abstrakcyjna:

  1. <?php
  2. abstract class kernel_Registry {
  3. private function _construct() {}
  4. abstract function get($key);
  5. abstract function set($key, $val);
  6. }
  7. ?>
Cysiaczek
Hmm... jakbym nie kombinował i tak zawsze jest ok. Coś musiałes gdzieś namieszać w kodzie użytkującym klasę. Wygląda na to, że coś przestawia Ci zmienną $dirty na false. Upewnij się, że tak się nie dzieje.

Tak na marginesie - możesz smiało wywalić konstruktor z klasy bazowej - nie jest potrzebny smile.gif

Pozdrawiam.
goffyy
Niestety to jednak php bo ja tylko ta klase do pliku wrzuclem i nie dziala sad.gif A co do konstruktora to masz racje.
drizzt73
ja mialem takie jaja z destruktorami kiedy wewnatrz destruktora jednej klasy odwolywalem sie do innej - ktora chyba niedoskonaly jeszcze w tym wzgledzie php pozwolil sobie juz zniszczyc. Pod www nie bylo tego w ogole widac, w shellu dopiero jak zaczalem sprawdzac to pojawil sie nawet segmentation fault. Dlatego popatrz jeszcze w miejsce gdzie ew. tak klasa moze sie niszczyc o ile nie jest to "naturalny" koniec.
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-2024 Invision Power Services, Inc.