Version complète: sur le forum Webmaster Hub : méthode récursive de destruction
Webmaster Hub > Création et exploitation de Sites Internet > Les langages du Net > PHP
ste
Bonjour, all...

je travaille sur un class dans laquelle j'implémente une méthode de destruction recursive qui me pose soucis à-priori :

code de la méthode :
CODE
function __delete_tmp($path)
    {
        $dir['tmp'] = dir($path);
        
        while($this->file['del'] = $dir['tmp']->read())
        {
            if(is_dir($this->file['del']))
            {
                $this->__delete_tmp($path.'/'.$this->file['del']);
                rmdir($this->file['del']);
            }
            else unlink($this->file['del']);
        }
        
        $dir['tmp']->close();
    }


quand je l'appelle ainsi '$this->__undelete_tmp(DIR.'/.')' où DIR est une constante, il me retourne Fatal error: Allowed memory size of 8388608 bytes exhausted (tried to allocate 3496 bytes) in /directory/script.php on line 125
la ligne 125 étant $this->__delete_tmp($path.'/'.$this->file['del']); dans la condition if(is_dir(...))

voili, voilou ... y'a certainement quelque chose qui cloche, mais là, je ne le vois pas.
merci d'avance.
ste
Bon, je me répons à moi-même :

j'ai oublié de gérer les fichiers '.' et '..' et je ne retournais pas sur le bon répertoire !
(erreurs de débutants ... tsss)

le bon code est celui-ci :
CODE
function __delete_tmp($path)
    {    
        $this->dir = opendir($path);
        
        /*** tant que la condition est correct en type alors on lit ***/
        while(false !== ($this->file['del'] = readdir($this->dir)))
        {
            if($this->file['del'] != '.' && $this->file['del'] != '..')
            {
                $this->path = $path.'/'.$this->file['del'];
                
                if(is_dir($this->path))
                {
                    $this->__delete_tmp($this->path);
                }
                else
                {
                    unlink($this->path);
                }
            }
        }
        
        closedir($this->dir);
        rmdir($path);
    }
ste
Bon, ça ne me dit pas pourquoi il ne fonctionne pas correctement !

???

il descend au répertoire le plus profond ...
et ne supprime strictement rien !

mad2.gif
Anonymus
D'un coté, tu as function __delete_tmp($path)
et de l'autre, tu appelles : $this->__undelete_tmp(DIR.'/.')'

Cherches tu au bon endroit ? wink.gif
ste
CITATION(Anonymus @ lundi 28 août 2006, 01h04) *
D'un coté, tu as function __delete_tmp($path)
et de l'autre, tu appelles : $this->__undelete_tmp(DIR.'/.')'

Cherches tu au bon endroit ? wink.gif


oui, oui ... enfin il me semble bien ...

arfff, pardon : je l'appelle bien par $this->__delete_tmp(DIR.'/.')'; et non $this->__undelete_tmp(DIR.'/.'); whistling.gif
rportal
est ce que ton script fonctionne, sinon pour voir pourquoi cela ne supprime pas, tu peux mettre des traces des repertoires et fichiers qu'il tente de supprimer...

une remarque pertinente sur ton code: tu utilises une méthode récursive avec une variable globale... Pas bon.

tes $this->path et $this->dir sont mis à jour à chaque appel de ta méthode mais quand tu sors de ta méthode (remontée de la récursivité), ces variables ne reviennent pas dans l'état désiré mais dans l'état inférieur, du coup cela ne fait pas grand chose, au mieux cela supprime le premier fichier de ta recherche récursive.
ste
Bon, eh bien, j'y suis enfin arrivé à le faire fonctionner.

Voici le code :
CODE
function __delete_tmp($path)
    {    //var_dump($path);
        chmod($path, 0777);
        $dir_tmp = opendir($path);
        
        /*** tant que la condition est juste en type alors on lit ***/
        while(false !== ($file_tmp = readdir($dir_tmp)))
        {
            if($file_tmp != '.' && $file_tmp != '..')
            {
                $path_tmp = $path.'/'.$file_tmp;
                
                if(!empty($path_tmp) && is_file($path_tmp))
                {
                    unlink($path_tmp);
                }
                else
                {
                    $this->__delete_tmp($path_tmp);
                }
            }
        }
        
        closedir($dir_tmp);
        rmdir($path);
    }


Pour ceux qui se demandent ce que cela change au fond, j'ai usé dans ce script de variable normale et non de variable array ...
ainsi la méthode fonctionne.

Et, pour info, et pour répondre à Anonymous, l'usage d'une variable globale dans l'appel de la méthode n'est en rien génant.
Une fois le script fonctionnel, j'ai testé avec et sans, et ça roule !!!

++
rportal
CITATION(ste @ lundi 28 août 2006, 22h37) *
Et, pour info, et pour répondre à Anonymous, l'usage d'une variable globale dans l'appel de la méthode n'est en rien génant.
Une fois le script fonctionnel, j'ai testé avec et sans, et ça roule !!!


De quel variable parles tu? $path ou les variables $*_tmp ? S'il s'agit de $path, effectivement cela pourrait fonctionner.Sinon la pile de retour des variables n'étant pas conservée (différence entre l'utilisation d'un environnement local et global), la récurrence ne peut pas s'exécuter comme désirée ($dir_tmp étant modifié par l'appel récursif). De manière générale, il n'est pas recommander d'utiliser des variables globales dans un récursion car le principe de la récursion repose sur la construction d'une pile de retour qui permet de rétablir l'environnement local d'une méthode après l'appel récursif.
Ceci est une version "bas débit" de notre forum. Pour voir la version complète avec plus d'information, la mise en page et les images, veuillez cliquer ici.