PHP - impossible d'ouvrir le flux : aucun fichier ou répertoire de ce type
P粉145543872
2023-08-23 16:30:33
<p>Dans un script PHP, que vous appeliez <code>include()</code>, <code>require()</code>, <code>fopen()</code> ou ses classes dérivées, telles que <code> include_once</code>, <code>require_once</code>, ou encore <code>move_uploaded_file()</code>, vous rencontrerez souvent des erreurs ou des avertissements : ≪ /p>
<blockquote>
<p>Impossible d'ouvrir le flux : aucun fichier ou répertoire de ce type. </p>
</blockquote>
<p>Quel est le bon processus pour trouver rapidement la cause première d’un problème ? </p>
Ajouté à la (très bonne) réponse existante
Logiciel d'hébergement partagé
open_basedir
可能会难倒您,因为它可以在 Web 服务器配置中指定。虽然如果您运行自己的专用服务器,这很容易解决,但有一些共享托管软件包(如 Plesk、cPanel 等)可以在每个域的基础上配置配置指令。由于该软件会构建配置文件(即httpd.conf
), vous ne pouvez donc pas modifier ce fichier directement car le logiciel d'hébergement l'écrasera simplement au redémarrage.Avec Plesk, ils fournissent un emplacement pour couvrir ce qu'ils ont à offrir
httpd.conf
(称为vhost.conf
). Seuls les administrateurs du serveur peuvent écrire dans ce fichier. La configuration Apache ressemble à ceciDemandez à votre administrateur de serveur de consulter les manuels des logiciels d'hébergement et de serveur Web qu'il utilise.
Autorisations de fichiers
Il est important de noter que l’exécution de fichiers via un serveur Web est très différente de l’exécution d’une ligne de commande ou d’une tâche cron. La plus grande différence est que votre serveur Web possède ses propres utilisateurs et autorisations. Cet utilisateur est fortement restreint pour des raisons de sécurité. Par exemple, Apache est généralement
apache
、www-data
或httpd
(selon votre serveur). Une tâche cron ou une exécution CLI a toutes les autorisations dont dispose l'utilisateur qui l'exécute (c'est-à-dire qu'un script PHP exécuté en tant que root s'exécutera avec les autorisations root).Souvent, les gens résolvent les problèmes d'autorisation en procédant comme suit (exemple Linux)
Ce n'est pas une bonne idée car le fichier ou le répertoire est désormais accessible en écriture par tout le monde. Si vous possédez le serveur et êtes le seul utilisateur, ce n'est pas grave, mais si vous êtes dans un environnement d'hébergement partagé, vous accordez l'accès à tout le monde sur le serveur.
Ce que vous devez faire est d'identifier les utilisateurs qui ont besoin d'un accès et de leur accorder l'accès uniquement. Une fois que vous savez quels utilisateurs ont besoin d'accéder, vous devez vous en assurer
Cet utilisateur est propriétaire du fichier et possède probablement le répertoire parent (en particulier le répertoire parent si vous écrivez dans le fichier). Dans la plupart des environnements d'hébergement partagé, cela ne posera pas de problème puisque votre utilisateur doit être propriétaire de tous les fichiers du répertoire racine. Un exemple Linux est présenté ci-dessous
Cet utilisateur (et uniquement cet utilisateur) a accès. Sous Linux, une bonne pratique est
chmod 600
(只有所有者可以读写)或chmod 644
(le propriétaire peut écrire, mais tout le monde peut lire)Vous pouvez lire une discussion plus large sur les autorisations et les utilisateurs Linux/Unix ici
Il existe de nombreuses raisons pour lesquelles vous pouvez rencontrer cette erreur, donc une bonne liste de contrôle de ce qu'il faut vérifier en premier peut être utile.
Supposons que nous résolvions la ligne suivante :
Liste de contrôle
1. Vérifiez le chemin du fichier pour les fautes de frappe
Ou déplacez l'appel de
require*
或include*
dans sa propre variable, faites-lui écho, copiez-le et essayez d'y accéder depuis le terminal :Puis, dans le terminal :
2. Vérifiez si le chemin du fichier des considérations de chemin relatif et absolu est correct
/users/tony/htdocs
Cela n'a donc rien à voir avec le chemin d'accès à la racine du site Web ou le chemin d'accès au fichier que vous saisissez-
Utilisez donc toujours des chemins de fichiers absolus-
Utilisez- constantes magiques
- Définissez vous-même une
require __DIR__ 。 “/相对/路径/来自/当前/文件”
。__DIR__
pour renvoyer le répertoire du fichier actuel.constante :
SITE_ROOT
Créez un fichier à la racine du répertoire du site par exemple-
- Écrivez
- Dans chaque fichier auquel vous souhaitez référencer le dossier racine du site, incluez
config.php
dans
config.php
, puis utilisez la constante
config.php
,然后在任意位置使用SITE_ROOT
n'importe où : p>Ces 2 pratiques rendent également votre application plus portable car elle ne repose pas sur les paramètres ini tels que les chemins d'inclusion.
3. Vérifiez vos chemins d'inclusion
Une autre façon d'inclure des fichiers, qui n'est ni relative ni purement absolue, consiste à s'appuyer sur le chemin d'inclusion. C'est souvent le cas des bibliothèques ou des frameworks tels que Zend Framework.
Une telle inclusion ressemblerait à ceci :
Dans ce cas, vous devez vous assurer que le dossier où se trouve "Zend" fait partie du chemin d'inclusion.
Vous pouvez vérifier le chemin d'inclusion à l'aide de la commande suivante :
Vous pouvez y ajouter des dossiers en utilisant la commande suivante :
4. Vérifiez si votre serveur a accès au fichier
Pour résumer, l'utilisateur qui exécute le processus serveur (Apache ou PHP) peut ne pas avoir du tout l'autorisation de lire ou d'écrire le fichier.
Pour vérifier sous quel utilisateur le serveur s'exécute, vous pouvez utiliser posix_getpwuid :
Pour retrouver les permissions d'un fichier, tapez la commande suivante dans le terminal :
Et consultez la notation d'autorisation
5. Vérifiez les paramètres PHP
Si aucune des méthodes ci-dessus ne fonctionne, le problème peut être que certains paramètres PHP l'empêchent d'accéder au fichier.
Trois paramètres peuvent être pertinents :
phpinfo()
phpinfo()
进行检查> 或使用ini_get("open_basedir")
ou en utilisantini_get("open_basedir")
ini_get("allow_url_include")
检查并使用ini_set("allow_url_include", "1")
ParamètresSituations extrêmes
Si aucune des méthodes ci-dessus ne permet de diagnostiquer le problème, certaines des situations particulières suivantes peuvent se produire :
1. Inclusion des bibliothèques qui dépendent des chemins d'inclusion
Vous pouvez inclure une bibliothèque, telle que le framework Zend, en utilisant un chemin relatif ou absolu. Par exemple :
Mais vous rencontrerez toujours le même type d’erreurs.
Cela se produit parce que le fichier que vous incluez (avec succès) lui-même a une instruction d'inclusion provenant d'un autre fichier, et la deuxième instruction d'inclusion suppose que vous avez ajouté le chemin d'accès à la bibliothèque au chemin d'inclusion.
Par exemple, le fichier du framework Zend mentionné précédemment peut contenir les éléments suivants :
Ni inclus via un chemin relatif ni inclus via un chemin absolu. On suppose que le répertoire du framework Zend a été ajouté au chemin d'inclusion.
Dans ce cas, la seule solution pratique est d'ajouter le répertoire au chemin d'inclusion.
2. SELinux
Si vous utilisez Linux à sécurité renforcée, cela peut être la cause du problème, car l'accès au fichier depuis le serveur est refusé.
Pour vérifier si SELinux est activé sur votre système, exécutez la commande
sestatus
dans le terminal. Si cette commande n'existe pas, SELinux n'existe pas sur votre système. S'il existe, il devrait vous indiquer s'il est appliqué.Pour vérifier si la politique SELinux est à l'origine du problème, vous pouvez essayer de la désactiver temporairement. Mais soyez prudent car cela désactivera complètement la protection. Ne faites pas cela sur un serveur de production.
Si vous n'avez plus de problèmes après avoir désactivé SELinux, alors c'est la cause première.
Pour résoudre ce problème, vous devez configurer SELinux en conséquence.
Les types de contexte suivants sont requis :
httpd_sys_content_t
pour les fichiers que vous souhaitez que le serveur puisse lirehttpd_sys_rw_content_t
pour les fichiers auxquels vous souhaitez accéder en lecture et en écriturehttpd_log_t
pour les fichiers journauxhttpd_cache_t
pour le répertoire de cachePar exemple, pour attribuer le type de contexte
httpd_sys_content_t
à la racine de votre site Web, exécutez :Si votre fichier se trouve dans votre répertoire personnel, vous devrez également ouvrir
httpd_enable_homedirs
Booléen :Quoi qu'il en soit, il peut y avoir plusieurs raisons pour lesquelles SELinux refuse l'accès à un fichier, en fonction de votre stratégie. Vous devez donc enquêter là-dessus. Voici un tutoriel spécifiquement pour configurer SELinux pour votre serveur Web.
3. Symphonie
Si vous utilisez Symfony et que vous rencontrez cette erreur lors du téléchargement sur le serveur, il est possible que le cache de votre application n'ait pas été réinitialisé depuis le téléchargement de
app/cache
, ou que le cache n'ait pas encore été vidé.Vous pouvez tester et résoudre ce problème en exécutant la commande de console suivante :
4. Caractères non ACSII dans les fichiers Zip
Apparemment, cette erreur se produit également lors de l'appel de
zip->close()
lorsque certains fichiers du zip contiennent des caractères non-ASCII (par exemple "é") dans leurs noms de fichiers.Une solution possible consiste à envelopper le nom de fichier dans
utf8_decode()
avant de créer le fichier cible.Merci à Fran Cano d'avoir identifié ce problème et proposé une solution