Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: dlaczego exit nie dziala jak nalezy?
Forum PHP.pl > Forum > PHP
qbs
witam wszystkich z gory na dol.
w dniu dzisiejszym, wraz z kumplem od spizowego kufla udalo nam sie znalezc pewna bardzo przykra rzecz. co prawda 99% osob ma to gdzies, jak i ja dotychczas, lecz w swojej ulomnosci nawet nie zdawalem sobie sprawy ze funkcja oferowana przez php, jaka jest exit() jest niezbyt poprawna. mianowicie, dziala ona w identyczny sposob jak die() i w brew temu co pisze w dokumentacji, mozna je bezczelnie obejsc. oczywiscie nie ma to wplywu na dzialanie poprawnie napisanego kodu, lecz dla osob poczatkujacych moze to byc zwyczajny "kwas" winksmiley.jpg

nie wiem czemu bylem przekonany, ze funkcja exit, zabija z miejsca watek w ktorym wykonywany jest skrypt (w przeciwienstwie do die ktory pozwala jeszcze destruktorom na dzialanie).

chcialem przez ten post zapytac czy jest cos co moglem pominac w dokumentacji, na tym forum tudziez konfiguracji php?

dla leniwych wrzucam kod winksmiley.jpg

Kod
<?php

class innaklasa
{

    public function __construct()
    {
    
        print "inna klasa<br />";
    }

    public function zrob()
    {
    
        try
        {
            
            throw new exception("test");
        }
        catch(Exception $e)
        {

            print "<pre>";
            print_r($e);
        }
    }
}

class klasa
{

    public function __construct()
    {
        
        print "konstruktor<br />";
    }
    public function __destruct()
    {

        print "destruktor<br />";
        $innaklasa = new innaklasa;
        $innaklasa->zrob();
    }
}

$c = new klasa;
exit;
nevt
nie wiem z jakiego manuala PHP korzystasz, ale najwyraźniej z kiepskiego. w najpopularniejszym manualu w opisie funkcji exit(...); pisze jak wół:
Cytat
Informacja: This language construct is equivalent to die().
qbs
auć, racja. mimo wszystko czemu ta funkcja nie potrafi zabic skrypt od reki? po kiego grzyba w takim razie die jest jeszcze stosowany? kompatybilnosc wstecz? kiedys zalecali uzywanie exit'a po die(), wiec?
deirathe
exit() nie exit;
mike
Cytat(deirathe @ 22.09.2008, 15:30:37 ) *
exit() nie exit;
Nie ma różnicy.
qbs
zadam pytanie troche inaczej bo jak teraz przeczytalem na spokojnie to sam nie wiem o co mi chodzi.
skoro exit() zamierzenie dziala tak jak die(), w jaki sposob mozna byc pewnym ze skrypt zakonczyl dzialanie? bo jak juz wiadomo odpalane sa jeszcze destruktory, w ktorych mozna robic co sie zywnie podoba.

btw, dzieki nevt, manuala na php.net nie odwiedzalem juz od dosc dawna, jesli chodzi o podstawy.
nevt
a tak przy okazji, pobawiłem się chwilę i znalazłem sposób na przerwanie skryptu bez odpalania destruktorów obiektów smile.gif wystarczy wygenerować FATAL ERROR (np. wywołanie niezdefiniowanej funkcji) i przykryć jego skutki operatorem @ ... to działa smile.gif
  1. <?php
  2. class innaklasa
  3. {
  4.    public function __construct()
  5.    {
  6.        print "inna klasa<br />";
  7.    }
  8.  
  9.    public function zrob()
  10.    {
  11.        try
  12.        {
  13.            throw new exception("test");
  14.        }
  15.        catch(Exception $e)
  16.        {
  17.            print "<pre>";
  18.            print_r($e);
  19.        }
  20.    }
  21. }
  22.  
  23. class klasa
  24. {
  25.    public function __construct()
  26.    {
  27.        print "konstruktor<br />";
  28.    }
  29.  
  30.    public function __destruct()
  31.    {
  32.        print "destruktor<br />";
  33.        $innaklasa = new innaklasa;
  34.        $innaklasa->zrob();
  35.    }
  36. }
  37.  
  38. $c = new klasa;
  39. @stop();
  40. ?>
qbs
dzieki nevt, ale rozczaruje cie. to dalej dziala blinksmiley.gif laugh.gif ale, przynajmniej mozna zrobic dosc prosto obsluge fatali.

no nic, nie ma co sie bawic w wynajdowanie dziury w calym, ewidetnie nie da sie zatrzymac watku z poziomu php. dzieki smile.gif
ddiceman
Zastanów się tak naprawdę, dlaczego tak jest a dojdziesz do tego, że jest to zamiarem a nie przypadkiem. Destruktor ma za zadanie wykonanie czynności przed usunięciem obiektu innych niż zwolnienie pamięci (co odbywa się samoczynnie). A zatem np. pokasowanie tymczasowych plików/tabel etc. Dlatego też zablokowanie obsługi destruktorów po exit()/die() powodowałoby pozostawianie w systemie różnorakich śmieci.
PHP przed zakończeniem wykonywania skryptu niszczy wszystkie referencje do wszystkich zadeklarowanych obiektów, co implikuje wywołanie destruktorów dla każdego obiektu. Nazywa się to cleanup routine
qbs
ddiceman, przeczytaj uwazniej o co mi chodzi. przede wszystkim, nie chodzi mi o mnie, gdyz skrypty pisac jeszcze w miare sensownie potrafie winksmiley.jpg cala historia zaczela sie od pewnej lamki co umiescila exita, a kod mimo to sie wykonywal dalej.
i wiem ze chodzi o zarzadzanie pamiecia itp stuff, poporstu chodzilo o to czy jest jakis sposob by upewnic sie ze skrypt zakonczyl dzialanie bez odpalania destruktorow. jak widac nie ma.

i wiem, ze w poprawnie napisanym skrypcie nie ma z tym problemu.
ddiceman
Przeczytałem uważnie - twierdzisz, że
Cytat
exit() jest poprostu schrzaniona

podczas gdy ja twierdzę, że to było zamiarem a nie przypadkiem.
I da się wstrzymać destruktory (dodaj do swojego przykładu z pierwszego posta):
  1. <?php
  2. $c = new klasa;
  3. overload('klasa');
  4. exit();
  5. ?>


edit: mój bład, PHP 4 only
qbs
ale to php4 smile.gif

poza tym nie twierdze ze to nie bylo zamierzone. skoro tak juz jest, to napewno bylo to zamierzone w mniejszym lub wiekszym stopniu. ale jak powiedzialem 3krotnie, chodzi mi o fakt zabicia skryptu od reki winksmiley.jpg
ddiceman
Sprawdzilem na PHP Version 5.2.3

edit: mój bład, PHP 4 only
qbs
dziwne, http://pl2.php.net/manual/pl/function.overload.php mowi co innego, a tymbardziej moja kompilacja php 5.2.5

Kod
konstruktor
Fatal error: Call to undefined function overload() in D:\htdocs\test.php on line 39
destruktor
inna klasa

Exception Object
(
    [message:protected] => test
    [string:private] =>
    [code:protected] => 0
    [file:protected] => D:\htdocs\test.php
    [line:protected] => 13
    [trace:private] => Array
        (
            [0] => Array
                (
                    [file] => D:\htdocs\test.php
                    [line] => 34
                    [function] => zrob
                    [class] => innaklasa
                    [type] => ->
                    [args] => Array
                        (
                        )

                )

            [1] => Array
                (
                    [function] => __destruct
                    [class] => klasa
                    [type] => ->
                    [args] => Array
                        (
                        )

                )

        )

)
ddiceman
Masz racje - rzeczywiscie tylko PHP4, na tym serwerze miałem maskowanie błędów, przepraszam.

Jedyne, co mi się teraz nasuwa to rozszerzenie PECL classkit

  1. <?php
  2. $c = new klasa;
  3. classkit_method_remove('klasa', '__destruct');
  4. exit();
  5. ?>


aczkolwiek nie jestem w stanie teraz tego sprawdzić.
qbs
e tam, szkoda twojego czasu. jedyna rada - nie pisac bzdur w destruktorach winksmiley.jpg dzieki za opinie i czas 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.