PHP-N'a pas réussi à ouvrir stream: aucun fichier ou répertoire de ce type

dans les scripts PHP, si l'appel include() , require() , fopen() , ou leurs dérivés tels que include_once , require_once , ou même, move_uploaded_file() , on rencontre souvent une erreur ou un avertissement:

N'a pas réussi à ouvrir stream : aucun fichier ou répertoire de ce type.

qu'est Ce qu'un bon processus pour trouver rapidement la cause racine du problème?

108
demandé sur Cœur 2016-04-12 17:58:40

5 réponses

il y a de nombreuses raisons pour lesquelles on pourrait tomber dans cette erreur et donc une bonne liste de contrôle de ce qu'il faut vérifier d'abord aide considérablement.

considérons que nous sommes en train de résoudre le problème de la ligne suivante:

require "/path/to/file"



Liste de contrôle



1. Vérifier le chemin du fichier pour les fautes de frappe

  • soit vérifier manuellement (en contrôlant visuellement le chemin)
  • ou de déplacer tout ce qui est appelé par require* ou include* à sa variable, d'écho, de le copier, et essayez d'accéder à partir d'un terminal:

    $path = "/path/to/file";
    
    echo "Path : $path";
    
    require "$path";
    

    puis, dans un terminal:

    cat <file path pasted>
    



2. Vérifiez que le chemin d'accès du fichier est correcte concernant Considérations relatives et absolues sur la trajectoire

  • s'il commence par une barre oblique " / " alors il ne se réfère pas à la racine du dossier de votre site web (la racine du document), mais à la racine de votre serveur.
    • par exemple, l'Annuaire de votre site Web pourrait être /users/tony/htdocs
  • si il ne commence pas par un slash ( / ), alors il est soit en s'appuyant sur le chemin de l' (voir ci-dessous) ou le chemin est relatif. S'il est relatif, alors PHP calculera relativement au chemin du répertoire de travail courant .
    • ainsi, pas relativement au chemin de la racine de votre site web, ou au fichier où vous tapez
    • pour cette raison, toujours utiliser des chemins de fichier absolus

meilleures pratiques:

afin de rendre votre script robuste en si vous déplacez des choses, tout en générant un chemin absolu à l'exécution, vous avez 2 options:

  1. utiliser require __DIR__ . "/relative/path/from/current/file" . La __DIR__ constante magique renvoie le répertoire du fichier courant.
  2. définir un SITE_ROOT constante de soi-même :

    • à la racine de l'Annuaire de votre site web, créez un fichier, par exemple config.php
    • dans config.php , d'écrire

      define('SITE_ROOT', __DIR__);
      
    • dans chaque fichier où vous voulez faire référence au dossier racine du site, incluez config.php , puis utilisez la constante SITE_ROOT où que vous aimiez:

      require_once __DIR__."/../config.php";
      ...
      require_once SITE_ROOT."/other/file.php";
      

ces 2 pratiques rendent également votre application plus portable parce qu'elle ne repose pas sur les paramètres ini comme le chemin d'inclusion.



3. Vérifiez votre chemin d'inclusion

une autre façon d'inclure des fichiers, ni relativement ni purement absolue, est de se fier au" chemin d'inclusion 15191250920 . C'est souvent le cas pour les bibliothèques ou les cadres tels que le cadre Zend.

une telle inclusion ressemblera à ceci:

include "Zend/Mail/Protocol/Imap.php"

Dans ce cas, vous voulez assurez-vous que le dossier où "Zend" est, fait partie du chemin.

vous pouvez vérifier le chemin d'inclusion avec:

echo get_include_path();

vous pouvez y ajouter un dossier avec:

set_include_path(get_include_path().":"."/path/to/new/folder");



4. Vérifiez que votre serveur a accès à ce fichier

il se peut que l'utilisateur qui exécute le processus serveur (Apache ou php) n'ait tout simplement pas l'autorisation de lire ou d'écrire dans ce fichier.

pour vérifier sous quel utilisateur le serveur exécute, vous pouvez utiliser posix_getpwuid :

$user = posix_getpwuid(posix_geteuid());

var_dump($user);

pour connaître les permissions sur le fichier, tapez la commande suivante dans le terminal:

ls -l <path/to/file>

et regardez permission notation symbolique



5. Vérifier les paramètres de PHP

si aucune des réponses ci-dessus n'a fonctionné, alors le problème est probablement que certains paramètres de PHP lui interdisent d'accéder à ce fichier.

trois réglages pourraient être pertinents:

  1. open_basedir
    • si cela est défini, PHP ne pourra pas accéder à un fichier en dehors du répertoire spécifié (pas même par un lien symbolique).
    • cependant, le comportement par défaut est qu'il ne doit pas être défini, auquel cas il n'y a pas de restriction
    • vous pouvez vérifier cela en appelant phpinfo() ou en utilisant ini_get("open_basedir")
    • vous pouvez modifier le paramètre soit en éditant votre php.fichier ini ou votre httpd.fichier conf
  2. mode sans échec
    • s'il s'agit tourné sur des restrictions peuvent s'appliquer. Cependant, ceci a été supprimé dans PHP 5.4. Si vous êtes toujours sur une version qui supporte la mise à niveau en mode de sécurité vers une version PHP qui est toujours supportée .
  3. allow_url_fopen et allow_url_include
    • ceci s'applique uniquement à l'inclusion ou à l'ouverture de fichiers par le biais d'un processus réseau tel que http:// système de fichiers local
    • cette valeur peut être vérifiée avec ini_get("allow_url_include") et définie avec ini_set("allow_url_include", "1")



Coin des affaires

si aucune des réponses ci-dessus n'a permis de diagnostiquer le problème, voici quelques situations spéciales qui pourraient se produire:



1. L'Inclusion de bibliothèque s'appuyant sur le chemin d'inclusion

il peut arriver que vous incluiez une bibliothèque, par exemple le cadre Zend, en utilisant un chemin relatif ou absolu. Par exemple:

require "/usr/share/php/libzend-framework-php/Zend/Mail/Protocol/Imap.php"

mais vous obtenez toujours le même type d'erreur.

cela pourrait se produire parce que le fichier que vous avez (avec succès) inclus, a lui-même une instruction include pour un autre fichier, et cette deuxième instruction include suppose que vous avez ajouté le chemin de la bibliothèque de l'include path.

par exemple, le fichier cadre de Zend mentionné ci-dessus pourrait contenir les éléments suivants :

include "Zend/Mail/Protocol/Exception.php" 

qui n'est ni une inclusion par un chemin relatif, ni par un chemin absolu. Il suppose que le répertoire du framework Zend a été ajouté au chemin include.

Dans un tel cas, la seule solution est d'ajouter le répertoire de votre chemin.



2. SELinux

si vous utilisez Linux amélioré par la sécurité, alors cela pourrait être la raison du problème, en refusant l'accès au fichier depuis le serveur.

pour vérifier si SELinux est activé sur votre système, lancez la commande sestatus dans un terminal. Si la commande n'existe pas, alors SELinux n'est pas sur votre système. Si elle n'existe pas, alors il devrait vous dire si elle est appliquée ou non.

pour vérifier si les politiques SELinux sont la raison pour le problème, vous pouvez essayer de l'éteindre Temporairement. Toutefois, soyez prudent, car cela désactivera entièrement la protection. Ne faites pas cela sur votre serveur de production.

setenforce 0

si vous n'avez plus le problème avec SELinux éteint, alors c'est la cause profonde.

à résolvez le , vous devrez configurer SELinux en conséquence.

les types de contexte suivants seront nécessaires:

  • httpd_sys_content_t pour les fichiers que vous voulez que votre serveur puisse lire
  • httpd_sys_rw_content_t pour les fichiers sur lesquels vous souhaitez accès en lecture et écriture
  • httpd_log_t pour les fichiers journaux
  • httpd_cache_t pour le répertoire de cache

par exemple, pour assigner le type de contexte httpd_sys_content_t à votre répertoire racine de site web, exécutez:

semanage fcontext -a -t httpd_sys_content_t "/path/to/root(/.*)?"
restorecon -Rv /path/to/root

si votre fichier est dans un répertoire personnel, vous devrez aussi activer le booléen httpd_enable_homedirs :

setsebool -P httpd_enable_homedirs 1

dans tous les cas, il pourrait y avoir une variété de raisons pour lesquelles SELinux refuserait l'accès à un fichier, selon vos politiques. De sorte que vous aurez besoin de se renseigner. ici est un tutoriel spécifique sur la configuration de SELinux pour un serveur web.



3. Symfony

si vous utilisez Symfony, et rencontrez cette erreur lors du téléchargement vers un serveur, alors il se peut que le cache de l'application n'ait pas été réinitialisé, soit parce que app/cache a été téléchargé, ou que le cache n'a pas été effacé.

vous pouvez le tester et le corriger en exécutant ce qui suit: commande de la console:

cache:clear



4. Non ACSII charactersinside Zip file

apparemment, cette erreur peut aussi se produire lors de l'appel zip->close() lorsque certains fichiers à l'intérieur du zip ont des caractères non ASCII dans leur nom de fichier, comme "é".

une solution possible consiste à envelopper le nom du fichier dans utf8_decode() avant de créer le fichier cible.

Crédits Fran Cano pour déterminer et de proposer une solution à ce problème

186
répondu Vic Seedoubleyew 2018-03-06 19:00:18

pour ajouter À la (très bonne) réponse existant

Logiciel D'Hébergement Partagé

open_basedir est un qui peut vous tromper parce qu'il peut être spécifié dans une configuration de serveur web. Bien qu'il soit facile de remédier à cette situation si vous utilisez votre propre serveur dédié, il existe des logiciels d'hébergement partagés (comme Plesk, cPanel, etc.) qui configureront une directive de configuration par domaine. Parce que le logiciel construit fichier de configuration (i.e. httpd.conf ) vous ne pouvez pas modifier ce fichier directement parce que le logiciel d'hébergement va juste l'écraser quand il redémarre.

avec Plesk, ils fournissent un endroit pour remplacer le httpd.conf fourni appelé vhost.conf . Seul l'administrateur du serveur peut écrire ce fichier. La configuration D'Apache ressemble à quelque chose comme ceci

<Directory /var/www/vhosts/domain.com>
    <IfModule mod_php5.c>
        php_admin_flag engine on
        php_admin_flag safe_mode off
        php_admin_value open_basedir "/var/www/vhosts/domain.com:/tmp:/usr/share/pear:/local/PEAR"
    </IfModule>
</Directory>

demandez à votre administrateur de serveur de consulter le manuel du logiciel d'hébergement et de serveur web utiliser.

Permissions De Fichiers

il est important de noter que l'exécution d'un fichier via votre serveur web est très différente de l'exécution d'une ligne de commande ou d'une tâche cron. La grande différence est que votre serveur web a ses propres utilisateurs et permissions. Pour des raisons de sécurité, cet utilisateur est assez restreint. Apache, par exemple, est souvent apache , www-data ou httpd (selon votre serveur). Une exécution cron ou CLI a toutes les permissions que l'utilisateur qui l'exécute a (c'est-à-dire que l'exécution d'un script PHP en tant que root s'exécutera avec les permissions de root).

beaucoup de fois les gens vont résoudre un problème de permissions en faisant ce qui suit (exemple Linux)

chmod 777 /path/to/file

ce n'est pas une idée intelligente, parce que le fichier ou le répertoire est maintenant accessible en écriture mondiale. Si vous possédez le serveur et êtes le seul utilisateur puis ce n'est pas une grosse affaire, mais si vous êtes sur un environnement d'hébergement partagé, vous venez de donner tout le monde sur votre serveur d'accès.

ce que vous devez faire est de déterminer les utilisateurs qui ont besoin d'accès et de ne donner accès qu'à ceux-là. Une fois que vous savez quels utilisateurs ont besoin d'accès, vous voulez vous assurer que

  1. "cet utilisateur possède le fichier et éventuellement le répertoire parent (en particulier le répertoire parent si vous voulez écrire des fichiers). Dans la plupart des environnements d'hébergement partagés, ce ne sera pas un problème, car l'utilisateur doit posséder tous les fichiers sous la racine de votre. Un exemple de Linux est montré ci-dessous

    chown apache:apache /path/to/file
    
  2. l'utilisateur, et seulement cet utilisateur, a accès. Sous Linux, une bonne pratique serait chmod 600 (seul le propriétaire peut lire et écrire) ou chmod 644 (propriétaire peut écrire, mais tout le monde peut lire)

vous pouvez lire une discussion plus approfondie sur les permissions Linux/Unix et les utilisateurs ici

11
répondu Machavity 2017-04-13 12:36:30

Ajouter un script avec les paramètres de la requête

C'était mon affaire. Il est en fait lié à question #4485874 , mais je vais l'expliquer ici sous peu.

Lorsque vous essayez de demander path/to/script.php?parameter=value , PHP recherche le fichier nommé script.php?parameter=value , car UNIX vous permet d'avoir des chemins comme celui-ci.

Si vous avez vraiment besoin de passer quelques données au script inclus, il suffit de le déclarer comme $variable=... ou $GLOBALS[]=... ou d'autres comme vous le souhaitez.

1
répondu Paul Lynn 2018-08-29 17:33:42

une autre cause possible: renommer et/ou déplacer des fichiers dans un éditeur de texte. Je suis passé par toutes les étapes ci-dessus sans succès jusqu'à ce que j'ai supprimé le fichier qui n'arrêtait pas de jeter cette erreur et créé un nouveau, qui a corrigé le problème.

0
répondu zMeadz 2017-11-30 01:40:56
  1. regardez le exact erreur

mon code a bien fonctionné sur toutes les machines mais seulement sur celle-ci a commencé à donner problème (qui avait l'habitude de travailler trouver je suppose). Utilisé echo "document_root" chemin de débogage et a également examiné de près l'erreur, trouvé ce ""

avertissement: inclure ( ) D:/MyProjects/testproject//functions/connections.php ): failed to open stream:

Vous pouvez facilement voir où sont les problèmes. Les problèmes sont // avant les fonctions

$document_root = $_SERVER['DOCUMENT_ROOT'];
echo "root: $document_root";
include($document_root.'/functions/connections.php');

donc il suffit de supprimer le chargement / de l'inclure et il devrait fonctionner très bien. Ce qui est intéressant, c'comportements différents sur les différentes versions. J'exécute le même code sur Ordinateur Portable, Macbook Pro et ce PC, tout a bien fonctionné jusqu'à présent. Espérons que cela aide quelqu'un.

  1. copier au-delà de l'emplacement du fichier dans le navigateur pour assurez-vous que le fichier existe. Parfois, les fichiers sont effacés de façon inattendue (ce qui s'est passé avec moi) et c'était aussi le problème dans mon cas.
-1
répondu Hammad Khan 2018-09-07 10:11:26