ugrás a tartalomhoz

PHP5 fájl létrehozása a destruktorban sikertelen

Hodicska Gergely · 2006. Már. 23. (Cs), 13.34
Sziasztok!


Egy tegnapi thread kapcsán próbáltam volna ki valamit, amikor a fenti hibába futottam.
<?php
	class foo {
		function __construct()
		{
			fopen(date('YmdHim').'.const.txt', 'w');
			mail('felho##kukac##x.hu', date('YmdHim').'.const.txt', '');
		}

		function __destruct()
		{
			fopen(date('YmdHim').'.dest.txt', 'w');
			mail('felho##kukac##x.hu', date('YmdHim').'.dest.txt', '');
		}
	}

	$foo = new foo();
	//$foo = 1;
?>
Ezt a kódot lefuttatva azt várnánk, hogy két fájl fog létrejönni, de érdekes módon csak egy keletkezik, még pedig az amit a konstruktorban hoztunk létre. A két mail megjön viszont rendesen, tehát a destruktor az lefutott.

Ha az utolsó sorben töröljük a kommentet, ami által kikényszerítjük az objektum megszűntetését még a script vége előtt, akkor viszont mindkét fájl létre fog jönni.

Ez így bug gyanús, de minimum olyan "feautre", amit dokumentációban jelölni kéne, ezért jeleztem a bugs.php.net-en.


Felhő
 
1

ez érdekes

virág · 2006. Már. 23. (Cs), 14.26
Szia,

bemásoltam a kódot amit írtál és valóban, semilyen más módon se fut le a fájl létrehozása. Hmmmm. Ez érdekes nagyon.
2

ilyenkor a motor már félig áll

Hodicska Gergely · 2006. Már. 23. (Cs), 14.52
Na azt válaszolták (némi RTFM körítéssel, miszerint olvass manuált és kérdezz okosan :)), hogy ez így teljesen normális, mert amikor a destruktorok lefutnak, akkor már a PHP motor jó része "áll", és pl. éppen ezért nem lehet már outputot sem kiadni belőle.

Ez utóbbi annyiban vicces, hogy pont a PHP manuálban lévő destruktor példában van print "nini itt vagyok". Annyit vissza is írtam, hogy ezt illene a manuálban is feltüntetni: pontosan mire is van lehetőségünk ott garázdálkodni. Pl. Ilia egyik slidejában láttam olyan példát, ahol a __destruct-ban fflush és fclose van (tehát szintén fájlműveletek) (bár lehet, hogy itt a kísérő szöveg az volt, hogy ilyet ne tegyünk ;)).


Felhő
3

félig áll :)

LeslieNice · 2006. Már. 23. (Cs), 15.28
Az RTFM-es dolgot nem bírták kihagyni :)

Egyre kiváncsibb vagyok a végeredményre, hogy a garázdálkodási lista meg fog e születni, mert ez a félig áll dolog, ez azért minden csak nem egzakt így. De legalább már fény derült arra, hogy a destruktorban azért van egy kisebb kalamajka és nem a hajunkat kell tépni ha nem megy valami a destruktorban.

(A nem létező objektumra történő destruktor hívásra nem kérdeztél rá véletlenül?)
4

létező objektumra történő destruktor hívás

Hodicska Gergely · 2006. Már. 23. (Cs), 16.05
A nem létező objektumra történő destruktor hívásra nem kérdeztél rá véletlenül?

Nem, mert ehhez kéne egy konkrét test case-t is produkálni. Esetleg tz produkálhatna egy ilyet, jó lenne annak is a végére járni.


Felhő
5

nincs is nemlétező objektum

zottty · 2006. Már. 23. (Cs), 20.30
Na, nagy nehezen sikerült kihekkelnem.

íme:

<?php
class foo
{
    public $member = "default value";
    
    function __construct(){
        new thrower( this );
    }
    
    function __destruct(){
        $this->fszom();
    }
    
    public function fszom(){
        sleep( 5 );        
    }
}

class thrower
{

    private $f;
    
    function __construct( $f ){
        $this->f = $f;
        try {
            throw new Exception( "foomessage" );
        } catch ( Exception $e ){
            echo "f::member: " . $this->f->member . "<br />";
            die;
        }
    }
}

$f = new foo();
?>


Azt, hogy mit csinál asszem nem kell magyarázni :)

Szóval:
sleep( 5 ) azért sleep(5) mert tényleg nem ehózik die után, így volt a legegyszerűbb megállapítani, hogy lefut-e.

Ami csudajó:
Először csináltam egy olyat, hogy a foo dobja az exceptiont, a 'main' elkapja, és kész. Nem die-ol, lefut a script - a destruktor nem fut le.

Aztán ugyanez, de a main dájol - a destruktor nem fut le.

Aztán így fut le: nem az foo osztály dobja/kapja az exceptiont, és a die-t sem az adja ki, hanem valami, amit a foo konstruktorából példányosítunk.

Ami gyönyörű, hogy amikor kiiratom a catch-nél f::membert, akkor nincs neki értéke. Pedig default értékkel kellene belelépnie a konstruktor törzsébe.
Mindenesetre az objektum "kicsit sem" készül el.

Szerintem.

z

--szerk--
p.s.
A a sleepet nem kell kulon fv-be tenni ( fszom() ) csak veletlen ugy maradt.
Itten is van, nem bug, igy kell mennie. :)
http://bugs.php.net/bug.php?id=36837
6

Válasz [2]-re

zottty · 2006. Már. 23. (Cs), 20.32
Linket tudnál dobni a bugreportról & válaszról?
7

parancsolj

Hodicska Gergely · 2006. Már. 23. (Cs), 23.46