goffyy
24.08.2006, 16:23:32
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

Z gory dzieki za podpowiedz.
nasty
24.08.2006, 16:28:10
tak dziala na wszystkich php5, podaj moze kod ?
goffyy
24.08.2006, 16:33:46
Kod jest banalny:
<?php
function __destruct() {
if ($this->dirty) $this->save();
}
?>
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
24.08.2006, 16:42:10
a napisz echo $this->dirty...
boc cos mi tu smierdzi falsem w $this->dirty
goffyy
24.08.2006, 16:46:25
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
nasty
24.08.2006, 16:47:40
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
24.08.2006, 16:55:32
Caly kod klasy:
<?php
class kernel_ApplicationRegistry extends kernel_Registry {
private $freezefile = "temp/ApplicationRegistry.txt";
private $values = array(); private $dirty = false;
private function __construct() {
$this->doReload($this);
}
if (!self::$instance) self::$instance = new self();
return self::$instance;
}
self::instance()->doReload();
}
private function doReload() {
$this->values = $array;
return true;
}
return false;
}
private function save() {
try {
file_put_contents($this->freezefile, $frozen, FILE_USE_INCLUDE_PATH);
} catch (KernelException $e) {
$e->__toString();
}
$this->dirty = false;
}
function get($key) {
return $this->values[$key];
}
function set($key, $val) {
$this->dirty = true;
$this->values[$key] = $val;
}
function isEmpty() {
return empty(self::instance()->values); }
function __destruct() {
if ($this->dirty) $this->save();
}
}
?>
Jak cos znajdziesz to daj znac
nasty
24.08.2006, 17:01:24
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
24.08.2006, 17:02:48
Jest ustalana na true tutaj:
<?php
function set($key, $val) {
$this->dirty = true;
$this->values[$key] = $val;
}
?>
Czyli w momencie jak ustawiasz jakas nowa zmienna lub jak zmianiasz istniejaca.
nasty
24.08.2006, 17:06:29
jesli ta funkcje wywolujesz, to powinno dzialac, jak nie to ja juz nieiwm
goffyy
24.08.2006, 17:12:12
ja tez nie wiem wlasnie

musze do admina napisac bo wyglada ze cos nie tak maja z php
nasty
24.08.2006, 17:14:40
admin tu ci nic nie pomoze, nie zawracaj mu glowy
hwao
24.08.2006, 18:56:58
a ja wiem

Dekstruktor jest generalnie zawsze wykonywany, ale jest z nim sporo problemow...
http://www.zyxist.com/pokaz.php/glupi_blad_phpO tu.

Zeby sprawdzic czy sie wlacza zrob po prostu
<?php
function __destruct() {
// echo nie bedzie widac, poniewaz dekstuktor
// zazwyczaj jest odpalany po skonczeniu przesylania danych do klienta http (czyli nie widzi juz tego)
// Zdebugujemy to tak
[b
]file_put_contents
( './test.txt', 'Desktruktor, uruchomiony'.date('d.m.Y h:i:s' ) ); [/b]
if ($this->dirty) $this->save();
}
?>
goffyy
24.08.2006, 19:51:57
Masz racje

Tylko ze u mnie nie dizala na razie w zaden sposob
mariuszn3
25.08.2006, 13:20:21
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
25.08.2006, 18:03:24
teoretycznie to i ja wiem ze tak powinno byc gorzej ze na tym serwerze co testuje nie jest
splatch
25.08.2006, 18:21:47
Może to głupie pytanie.. ale masz jakąś instancje tej klasy [stworzony obiekt]?
nasty
25.08.2006, 18:22:35
a wez w construct napisz :
<?php
$this->__destruct();
?>
i zobacz czy wykona ..., bo jak nie to ....
goffyy
25.08.2006, 20:51:43
W ten sposob dziala wszystko poprawnie a wiec to wina php jakas
Cysiaczek
25.08.2006, 21:49:58
Możesz pokazac klasę bazową?
goffyy
25.08.2006, 22:20:07
To jest prosta klasa abstrakcyjna:
<?php
abstract class kernel_Registry {
private function _construct() {}
abstract function get($key);
abstract function set($key, $val);
}
?>
Cysiaczek
25.08.2006, 22:44:26
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

Pozdrawiam.
goffyy
25.08.2006, 23:13:44
Niestety to jednak php bo ja tylko ta klase do pliku wrzuclem i nie dziala

A co do konstruktora to masz racje.
drizzt73
29.08.2006, 21:49:36
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.