Aller au contenu | Aller au menu | Aller à la recherche
Lors d'un exercice en Licence Professionnelle Informatique Web Développeur à l'INSSET de Saint-Quentin, mes élèves ont constaté un comportement étrange avec le destructeur d'une classe. Voici un exemple minimal du problème :
<?php
class Exemple
{
public function __destruct()
{
file_put_contents('log.txt', 'Test');
}
}
$exemple = new Exemple();
Ce code ne pose a priori pas de problème et pourtant si vous l'exécutez avec Apache sur Unix vous risquez d'avoir des problèmes de droit d'écriture :
Warning: file_put_contents(log.txt) [function.file-put-contents]: failed to open stream: Permission denied in /var/www/test/destruct.php on line 6
En fait l'explication est aussi étonnante que simple et comme souvent on la trouve dans la documentation de PHP : lors de la phase de clôture d'un script, le contexte peut changer sur certains SAPI dont Apache.
Cela veux dire que notre instance étant détruite implicitement lors de la clôture du script, PHP ne va pas essayer de créer le fichier, dont le chemin est relatif, dans le même répertoire que le script mais dans un autre répertoire où il n'a pas forcément le droit d'écrire.
Pour contourner ce problème, il suffit soit de donner au fichier un chemin absolu pour le fichier, soit de détruire explicitement l'instance afin que cela se fasse avant la phase de clôture du script :
$exemple = null
ou
unset($exemple);
vendredi 11 décembre 2009 à 20h16 -
PHP
Aucun rétrolien pour le moment.
Les rétroliens pour ce billet sont fermés.
![]()
Logique mais fallait le trouver !
Seza
le vendredi 11 décembre 2009 à 21h49
![]()
C'est vrai qu'on a mis du temps a trouvé le problème !
Un élève
le vendredi 11 décembre 2009 à 23h51
![]()
D'une manière générale, tous les chemins devraient être pleinement qualifiés
![]()
Tout a fait d'accord avec Hervé, que ce soit avec __DIR__ de php 5.3 ou dirname(__FILE__) des version antérieur, il est aisé de récupérer le chemin absolue d'un dossier de travail et travailler plus sereinement.
![]()
J'approuve complètement la bonne pratique sur l'utilisation de chemins complets.
Ceci mis à part c'est toujours intérressant de comprendre les différents comportements de PHP.
Martin
le lundi 14 décembre 2009 à 13h05
![]()
Cependant le problème peut persister dans le cas ou il resterait des références sur cet objet.
En php5 la manipulation d'objet se faisant par référence le cas suivant poserais encore problèmes :
$exemple = new Exemple();
// ...
$exemple2 = $exemple;
unset($exemple);
C'est donc Hervé qui est dans le vrai ; tous les chemins devraient être pleinement qualifiés.
Méthylbro
le lundi 14 décembre 2009 à 18h40
Les commentaires pour ce billet sont fermés.
© 2003-2010 Jean-Marc Fontaine - Tous droits réservés
XHTML - CSS - DotClear - Technorati
Les billets de ce blog sont sous licence Creative Commons
stopher le vendredi 11 décembre 2009 à 19h48