web-dev-qa-db-fra.com

file_exists () renvoie false, mais le fichier n'existe pas

J'ai un problème très étrange avec file_exists (). J'utilise cette fonction pour vérifier si 2 fichiers différents dans les mêmes dossiers existent. J'ai vérifié, ils ENCORE existent.

echo $relative . $url['path'] . '/' . $path['filename'] . '.jpg';
Result: ../../images/example/001-001.jpg

echo $relative . $url['path'] . '/' . $path['filename'] . '.' . $path['extension'];
Result: ../../images/example/001-001.PNG

Maintenant, utilisons file_exists () sur ceux-ci:

var_dump(file_exists($relative . $url['path'] . '/' . $path['filename'] . '.jpg'));
Result: bool(false)

var_dump(file_exists($relative . $url['path'] . '/' . $path['filename'] . '.' . $path['extension']));
Result: bool(true)

Je ne comprends pas, ces deux fichiers existent. J'utilise Windows, donc ce n'est pas lié à un problème sensible à la casse. Le mode sans échec est désactivé.

Il convient toutefois de mentionner que le fichier .png est téléchargé par un utilisateur via FTP, tandis que le fichier .jpg est créé à l’aide d’un script. Mais pour autant que je sache, cela ne devrait pas faire de différence.

Des conseils?

Merci

29
Bv202

Les résultats de file_exists() sont mis en cache. Essayez donc d'utiliser clearstatcache(). Si cela ne vous aide pas, revérifiez les noms - ils pourraient être similaires, mais pas les mêmes.

19
Timur

J'ai trouvé que ce qui fonctionne pour moi pour vérifier si un fichier existe (par rapport au fichier php actuel à partir duquel il est exécuté) est ce morceau de code:

$filename = 'myfile.jpg';
$file_path_and_name = dirname(__FILE__) . DIRECTORY_SEPARATOR . "{$filename}";
if ( file_exists($file_path_and_name) ){
  // file exists. Do some magic...              
} else {
  // file does not exists...
}
12
Shahar

C'est à cause du mode sans échec. Vous pouvez le désactiver ou inclure le répertoire dans safe_mode_include_dir. Ou modifiez la propriété/les autorisations de fichier pour ces fichiers.

php.net: file_exists ()
php.net: mode sans échec

11
ace

file_exists() ne fonctionne tout simplement pas avec les adresses HTTP. 

Il ne supporte que les chemins de système de fichiers (et FTP, si vous utilisez PHP5.)

notez s'il vous plaît:

travaillé :

if  (file_exists($_SERVER['DOCUMENT_ROOT']."/folder/test.txt") 
    echo "file exists";

pas travaillé :

if (file_exists("www.mysite.com/folder/test.txt") 
    echo "file exists";
11
Mahdi Loghmani

Juste mon $ .02: Je viens d'avoir ce problème et c'était en raison d'un espace à la fin du nom du fichier. Ce n'est pas toujours un problème de chemin - bien que ce soit la première chose que je vérifie - toujours. Je pourrais couper et coller le nom du fichier dans une fenêtre Shell à l’aide de la commande ls -l et, bien sûr, localiser le fichier car la ligne de commande ignore l’espace où le fichier n'existe pas. Très frustrant et presque impossible à localiser sans StackOverflow.

CONSEIL: lors de la sortie des instructions de débogage, indiquez des délimiteurs () ou [], ce qui indiquera un espace assez clairement. Et rappelez-vous toujours de couper votre entrée.

9
Brian

Essayez d'utiliser DIRECTORY_SEPARATOR au lieu de '/' comme séparateur. Windows utilise un séparateur différent pour les chemins de système de fichiers (barre oblique inverse) par rapport aux systèmes Linux et Unix.

2
Doug

Il peut également s'agir d'un problème d'autorisation sur l'un des dossiers parents ou sur le fichier lui-même.

Essayez d’ouvrir une session en tant qu’utilisateur exécutant votre serveur Web et le cd. Le dossier doit être accessible par cet utilisateur et le fichier doit être lisible.

Sinon, php retournera que le fichier n'existe pas.

1
Julien Ricard

Une astuce très simple est ici qui a fonctionné pour moi.

Lorsque j'écris la ligne suivante, elle renvoie false.

if(file_exists('/my-dreams-files/'.$_GET['article'].'.html'))

Et lorsque j’écris en supprimant l’adresse URL de départ, elle renvoie true.

if(file_exists('my-dreams-files/'.$_GET['article'].'.html'))
1
Mangilal Sharma

La raison pour laquelle cela se produit est nouvelle: j'utilise PHP dans un conteneur Docker avec un volume monté pour la base de code qui réside sur ma machine hôte locale.

Je recevais file_exists == FALSE (dans Composer autoload), mais si je copiais la filepath dans le terminal, il existait! J'ai essayé le clearstatche(), vérifié que le mode sans échec était désactivé.

Je me suis ensuite rappelé le mappage de volume Docker: le chemin absolu sur mon ordinateur hôte local n’existe certainement pas à l’intérieur du conteneur Docker - qui est la perspective de PHP sur le monde.

(Je ne cesse d'oublier que j'utilise Docker, car j'ai créé des fonctions Shell qui enveloppent les commandes d'exécution du docker de manière aussi agréable ...)

1
scipilot

Cette réponse est peut-être un peu compliquée, mais cela a fonctionné pour moi -

$file = 'path/to/file.jpg';
$file = $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_Host'].'/'.$file;
$file_headers = @get_headers($file);
if($file_headers[0] == 'HTTP/1.1 404 Not Found') {
    $exists = false;
}else{
    $exists = true;
}

apparemment $_SERVER['REQUEST_SCHEME'] est un peu risqué à utiliser avec IIS 7.0 + PHP 5.3 afin que vous puissiez probablement trouver un meilleur moyen d’ajouter du protocole.

J'ai trouvé cette réponse ici http://php.net/manual/en/function.file-exists.php#75064

0
kiko carisse

J'ai passé les deux dernières heures à me demander ce qui n'allait pas avec ma déclaration if: file_exists($file) renvoyait false, mais je pouvais appeler include($file) sans problème.

Il s’avère que je n’ai pas réalisé que la valeur php include_path que j’avais définie dans le fichier .htaccess n’était pas reportée à file_exists, is_file, etc.

Ainsi:

<?PHP
// .htaccess php_value include_path '/home/user/public_html/';

// includes lies in /home/user/public_html/includes/

//doesn't work, file_exists returns false
if ( file_exists('includes/config.php') )
{
     include('includes/config.php');
}

//does work, file_exists returns true
if ( file_exists('/home/user/public_html/includes/config.php') )
{
    include('includes/config.php');
}
?>

Cela montre simplement que les "raccourcis pour plus de simplicité", comme la définition de include_path dans .htaccess, peuvent causer plus de deuil à long terme.

0
Irshad Khan

avez-vous essayé la saisie manuelle. aussi vos deux extensions semblent être dans un cas différent

   var_dump(file_exists('../../images/example/001-001.jpg'));
   var_dump(file_exists('../../images/example/001-001.PNG'));
0
amigura

Une fonction custom_file_exists () inspirée par les réponses précédentes de @ Timur, @ Brian, @Doug et @Shahar:

function custom_file_exists($file_path=''){
    $file_exists=false;

    //clear cached results
    //clearstatcache();

    //trim path
    $file_dir=trim(dirname($file_path));

    //normalize path separator
    $file_dir=str_replace('/',DIRECTORY_SEPARATOR,$file_dir).DIRECTORY_SEPARATOR;

    //trim file name
    $file_name=trim(basename($file_path));

    //rebuild path
    $file_path=$file_dir."{$file_name}";

    //If you simply want to check that some file (not directory) exists, 
    //and concerned about performance, try is_file() instead.
    //It seems like is_file() is almost 2x faster when a file exists 
    //and about the same when it doesn't.

    $file_exists=is_file($file_path);

    //$file_exists=file_exists($file_path);

    return $file_exists;
}
0
RafaSashi