Dur Comme Faire

Aller au contenu | Aller au menu | Aller à la recherche

Attention au contexte d'exécution des destructeurs

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 Fil de syndication

Rétroliens

Aucun rétrolien pour le moment.

Les rétroliens pour ce billet sont fermés.

Commentaires

Gravatar de stopher

Intéressant ,
Il fallait le trouver :-)

Ch.

stopher le vendredi 11 décembre 2009 à 19h48 Icone du permalien

Gravatar de Seza

Logique mais fallait le trouver !

Seza le vendredi 11 décembre 2009 à 21h49 Icone du permalien

Gravatar de Un élève

C'est vrai qu'on a mis du temps a trouvé le problème !

Un élève le vendredi 11 décembre 2009 à 23h51 Icone du permalien

Gravatar de Hervé

D'une manière générale, tous les chemins devraient être pleinement qualifiés

Hervé le samedi 12 décembre 2009 à 09h45 Icone du permalien

Gravatar de Revlis

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.

Revlis le dimanche 13 décembre 2009 à 18h11 Icone du permalien

Gravatar de Martin

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 Icone du permalien

Gravatar de Méthylbro

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 Icone du permalien

Ajouter un commentaire

Les commentaires pour ce billet sont fermés.

XHTML - CSS - DotClear - Technorati

Les billets de ce blog sont sous licence Creative Commons