__destruct et __construct sont dans un bateau ....

Eléphant du PHP | 254 Messages

19 mars 2006, 02:59

depuis le temps que je voulais poser la question pour avoir un avis exterieur, j'en profite pendant que je suis dans le coin :D

exemple :
class Test{
	function __construct(){
		print('coucou, je suis <b>'.__METHOD__.'</b><hr />');
	}
	function __destruct(){
		print('au revoir, je suis <b>'.__METHOD__.'</b><hr />');
	}
}

new Test();
affichage :
coucou, je suis Test::__construct
--------------------------------------------------------------------------------
au revoir, je suis Test::__destruct
--------------------------------------------------------------------------------
dans la doc
http://fr2.php.net/manual/fr/language.oop5.decon.php

1-"La méthode destructeur doit être appelée aussitôt que toutes les références à un objet particulier sont effacées ou lorsque l'objet est explicitement détruit."

et aussi
2-"Note : Le destructeur est appelé durant l'arrêt du script, donc les en-têtes sont toujours déjà envoyés."


1-hors je reve pas, je n'ai pas eu besoin d'appeller le destructeur et pourtant il est executé lors de la destruction de la classe.

2-une autre chose bizarre, le destructeur m'affiche bien le texte



vous avez le meme comportement ?
PHP 5.0.4


merci

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

19 mars 2006, 04:22

En fin de script (ou dès que l'on sort du scope, par exemple au moment d'exécuter un return dans une fonction) toutes les variables sont détruites, ça explique pourquoi __destruct est exécuté en fin de script.

Quant à l'affichage... je ne connais pas en détail la procédure d'arrêt (shutdown) de PHP, mais ça semble assez logique: la procédure fait, par définition, partie du cycle de vie d'un script donc elle se produit avant que le module PHP ait fini son travail et qu'Apache ait fini d'envoyer la page. Je ne sais pas si je suis très clair, désolé :roll:

Eléphant du PHP | 254 Messages

19 mars 2006, 04:34

bon sang ... je viens de comprendre ma betise .... :x

connaitre la DOC PHP par coeur et comprendre la DOC sont 2 choses differentes .... surtout faire bien attention a ce que je peux lire :(


pour le "-2" : la DOC parle d'en-têtes et j'etais tout simplement persuadé que tout ce qui etait destiné a l'affichage etait deja envoyé ... que plus rien ne pouvait etre affiché.

:arrow: bon, je retourne scripter, c'est la bonne heure :D


merci :)

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

19 mars 2006, 04:39

Concernant les destructors, même la doc n'a pas toutes les réponses et il se peut que tu tombes sur des trucs incompréhensibles de temps à autres. Historiquement, l'ordre d'exécutions des destructors (affectueusement surnommés dtors) a même changé plusieurs fois, parfois à quelques jours d'intervalles.

Dans le registre des trucs "pas évidents" que j'ai pu rencontrer:
function __destruct()
{
   file_put_contents('./test.txt', 'devine où je suis');
}

Eléphant du PHP | 254 Messages

19 mars 2006, 04:47

apres le test : il est crée dans le meme repertoire que le script executé ... donc rien ne me parrait illogique .

pourquoi, tu as pas du tout le meme comportement sur ton serveur ?

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

19 mars 2006, 04:51

Selon les cas, je l'ai déjà vu créé dans C:\ ou dans mon répertoire Apache. Depuis, je m'assure toujours d'avoir un realpath() du répertoire en cours quelque part accessible (constante par exemple).

Mammouth du PHP | 684 Messages

10 avr. 2006, 17:06

Je continue un peu la discution sur le destructeur.
Selon les cas, je l'ai déjà vu créé dans C:\ ou dans mon répertoire Apache. Depuis, je m'assure toujours d'avoir un realpath() du répertoire en cours quelque part accessible (constante par exemple).
C'est effectivement tres bizarre comme comportement. Voici un bout de script fait par mes dix doigts :
<?php
echo 'Le pwd est : ['.getcwd().']<br />';
class TestCwd
{
    public function __construct()
    {
        echo 'Le pwd est : ['.getcwd().'] pour le constructeur.<br />';
    }

    public function __destruct()
    {
        echo 'Le pwd est : ['.getcwd().'] pour le destructeur.<br />';
    }

    public function pwd()
    {
        echo 'Le pwd est : ['.getcwd().'] pour la methode TestCwd::pwd().<br />';
    }
}
$test = new TestCwd();
$test->pwd();
echo 'Le pwd est : ['.getcwd().'] pour la fin.<br />';
?>
Voici le resultat :

Code : Tout sélectionner

Le pwd est : [/var/www/html/test] Le pwd est : [/var/www/html/test] pour le constructeur. Le pwd est : [/var/www/html/test] pour la methode TestCwd::pwd(). Le pwd est : [/var/www/html/test] pour la fin. Le pwd est : [/] pour le destructeur. <<<--- C'est interessant.
Je me pose donc la question, pourquoi ??? :)

Quelqu'un a une reponse ? Est-ce un bug ou normal ?

Merci pour vos reponses.
Zigz4g

Mammouth du PHP | 684 Messages

10 avr. 2006, 17:18

Bon je me reponds en fonction des reports de bug trouves sur bugs.php.net.
Si je comprend les reponses donnees, c'est un probleme avec Apache.
Voici les commentaires des developpeurs de php :
This really should be documented. Apache(1&2) does the weird
cwd change for some reason.
et
It's because of Apache which changes the current working dir at some
point(s). Not PHP bug to be fixed.
Je donnes les liens :
http://bugs.php.net/bug.php?id=34206
http://bugs.php.net/bug.php?id=36454
Zigz4g

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

11 avr. 2006, 10:53

Est-ce un bug ou normal ?
Pas vraiment un bug (à part pour la fois où le fichier à été créé en dehors du docroot d'Apache, çà, c'était un bug mais c'était il y a quelques temps déjà et je n'ai pas pu le reproduire depuis) plutôt une zone d'ombre du manuel. __destruct() s'exécute dans un environnement particulier, il suffit de le savoir. Ça mériterait d'être mieux documenté en effet :(

Mammouth du PHP | 684 Messages

11 avr. 2006, 11:02

Cela ne m'ériterait-il pas d'être dans une faq de phpfrance ???
Ou ne serait-il pas interessant de le signaler à PHP.net pour l'ajouter dans la documentation en reportant une requête sur bugs.php.net ?
Zigz4g