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.
  1. <?php  
  2.     class foo {  
  3.         function __construct()  
  4.         {  
  5.             fopen(date('YmdHim').'.const.txt''w');  
  6.             mail('felho##kukac##x.hu'date('YmdHim').'.const.txt''');  
  7.         }  
  8.   
  9.         function __destruct()  
  10.         {  
  11.             fopen(date('YmdHim').'.dest.txt''w');  
  12.             mail('felho##kukac##x.hu'date('YmdHim').'.dest.txt''');  
  13.         }  
  14.     }  
  15.   
  16.     $foo = new foo();  
  17.     //$foo = 1;  
  18. ?>  
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:
  1. <?php  
  2. class foo  
  3. {  
  4.     public $member = "default value";  
  5.       
  6.     function __construct(){  
  7.         new thrower( this );  
  8.     }  
  9.       
  10.     function __destruct(){  
  11.         $this->fszom();  
  12.     }  
  13.       
  14.     public function fszom(){  
  15.         sleep( 5 );          
  16.     }  
  17. }  
  18.   
  19. class thrower  
  20. {  
  21.   
  22.     private $f;  
  23.       
  24.     function __construct( $f ){  
  25.         $this->f = $f;  
  26.         try {  
  27.             throw new Exception( "foomessage" );  
  28.         } catch ( Exception $e ){  
  29.             echo "f::member: " . $this->f->member . "<br />";  
  30.             die;  
  31.         }  
  32.     }  
  33. }  
  34.   
  35. $f = new foo();  
  36. ?>  


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