2010-05-25 3 views
0

Est-ce que quelqu'un connaît une solution à ce problème? Je suis incapable d'ouvrir un sous-répertoire dans un répertoire symboliclink'd. J'ai confirmé que les chemins sont corrects (même copier & collé le chemin dans l'explorateur, qui l'a analysé très bien). Ceci est un bug étrange, ennuyeux: |.PHP/Windows - Opendir() échoue ouverture des sous-répertoires dans les répertoires liés symboliques

Exemple:

C: \ dossier \ symbolic_link \ rep1 \ dir2 - dir2 d'ouverture échoue.

dossier C: \ \ symbolic_link \ dir1 - fonctionne

dossier C: \ \ real_directory \ dir1 \ dir2 - fonctionne

dossier C: \ \ real_directory \ dir1 - Travaux

+0

Cela fonctionne dans l'explorateur, mais le iis_user a-t-il les permissions pour le voir? –

+0

@Dan Thx! mais je suis en train d'exécuter apache (pile XAMPP LAMP), ça semble être un bug avec opendir() de php. J'ai trouvé un rapport de bug PHP datant de 2008 qui n'a pas été corrigé dans 5.3: /. –

Répondre

0

D'accord, j'ai finalement trouvé un bidouillage pour résoudre ce bug dans la gestion par PHP des liens symboliques sur Windows. Le bogue se produit lors de l'itération récursive des fichiers/répertoires en utilisant opendir(). Si un lien symbolique vers un répertoire existe dans le répertoire en cours, opendir() ne parviendra pas à lire les répertoires dans le répertoire symlink. Il est causé par quelque chose de funky dans le statcache de php, et peut être résolu en appelant clearstatcache() avant d'appeler opendir() sur le lien symbolique (aussi, le gestionnaire de fichiers du répertoire parent doit être fermé).

Voici un exemple du correctif:

<?php 

class Filesystem 
{ 
    public static function files($path, $stats = FALSE) 
    { 
     clearstatcache(); 

     $ret = array(); 
     $handle = opendir($path); 
     $files = array(); 

     // Store files in directory, subdirectories can't be read until current handle is closed & statcache cleared. 
     while (FALSE !== ($file = readdir($handle))) 
     { 
      if ($file != '.' && $file != '..') 
      { 
       $files[] = $file; 
      } 
     } 

     // Handle _must_ be closed before statcache is cleared, cache from open handles won't be cleared! 
     closedir($handle); 

     foreach ($files as $file) 
     { 
     clearstatcache($path); 

      if (is_dir($path . '/' . $file)) 
      { 
       $dir_files = self::files($path . '/' . $file); 

       foreach ($dir_files as $dir_file) 
       { 
        $ret[] = $file . '/' . $dir_file; 
       } 
      } 
      else if (is_file($path . '/' . $file)) 
      { 
       $ret[] = $file; 
      } 
     } 

     return $ret; 
    } 
} 

var_dump(filessystem::files('c:\\some_path')); 

Edit: Il semble que clearstatcache($path) doit être appelée avant toutes les fonctions de traitement de fichiers sur le symlink'd dir. Php ne met pas correctement en cache les répertoires symlink'd.

Questions connexes