Il y a de nombreuses raisons pour lesquelles on pourrait rencontrer cette erreur et donc une bonne liste de contrôle de ce qu'il faut vérifier en premier aide considérablement.
Considérons que nous résolvons la ligne suivante:
require "/path/to/file"
Liste de contrôle
1. Vérifiez le chemin du fichier pour les fautes de frappe
- soit vérifier manuellement (en vérifiant visuellement le chemin)
ou déplacez tout ce qui est appelé par require*
ou include*
vers sa propre variable, faites-en écho, copiez-le et essayez d'y accéder depuis un terminal:
$path = "/path/to/file";
echo "Path : $path";
require "$path";
Ensuite, dans un terminal:
cat <file path pasted>
2. Vérifiez que le chemin du fichier est correct en ce qui concerne les considérations relatives au chemin absolu ou relatif
- s'il commence par une barre oblique "/", il ne fait pas référence à la racine du dossier de votre site Web (la racine du document), mais à la racine de votre serveur.
- par exemple, le répertoire de votre site Web pourrait être
/users/tony/htdocs
- s'il ne commence pas par une barre oblique, alors il s'appuie sur le chemin d'inclusion (voir ci-dessous) ou le chemin est relatif. S'il est relatif, PHP calculera par rapport au chemin du répertoire de travail actuel .
- donc, pas par rapport au chemin de la racine de votre site Web, ou au fichier dans lequel vous tapez
- pour cette raison, utilisez toujours des chemins de fichiers absolus
Les meilleures pratiques :
Afin de rendre votre script robuste au cas où vous déplacez des éléments, tout en générant un chemin absolu à l'exécution, vous avez 2 options:
- utiliser
require __DIR__ . "/relative/path/from/current/file"
. La __DIR__
constante magique renvoie le répertoire du fichier courant.
définissez SITE_ROOT
vous-même une constante:
- à la racine du répertoire de votre site Web, créez un fichier, par exemple
config.php
dans config.php
, écris
define('SITE_ROOT', __DIR__);
dans chaque fichier où vous souhaitez référencer le dossier racine du site, incluez config.php
, puis utilisez la SITE_ROOT
constante où vous le souhaitez:
require_once __DIR__."/../config.php";
...
require_once SITE_ROOT."/other/file.php";
Ces 2 pratiques rendent également votre application plus portable car elle ne repose pas sur des paramètres ini comme le chemin d'inclusion.
3. Vérifiez votre chemin d’inclusion
Une autre façon d'inclure des fichiers, ni de manière relativement ni purement absolue, consiste à s'appuyer sur le chemin d'inclusion . C'est souvent le cas pour les bibliothèques ou les frameworks tels que le framework Zend.
Une telle inclusion ressemblera à ceci:
include "Zend/Mail/Protocol/Imap.php"
Dans ce cas, vous voudrez vous assurer que le dossier où se trouve "Zend" fait partie du chemin d'inclusion.
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 dans l'ensemble, l'utilisateur exécutant 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 tourne, vous pouvez utiliser posix_getpwuid :
$user = posix_getpwuid(posix_geteuid());
var_dump($user);
Pour connaître les autorisations sur le fichier, tapez la commande suivante dans le terminal:
ls -l <path/to/file>
et regardez la notation symbolique des autorisations
5. Vérifiez les paramètres PHP
Si rien de ce qui précède n'a fonctionné, le problème est probablement que certains paramètres PHP lui interdisent d'accéder à ce fichier.
Trois paramètres peuvent être pertinents:
- open_basedir
- Si cela est défini, PHP ne pourra accéder à aucun fichier en dehors du répertoire spécifié (même pas via un lien symbolique).
- Cependant, le comportement par défaut est qu'il ne soit pas défini, auquel cas il n'y a pas de restriction
- Cela peut être vérifié en appelant
phpinfo()
ou en utilisantini_get("open_basedir")
- Vous pouvez modifier le paramètre en éditant votre fichier php.ini ou votre fichier httpd.conf
- mode sans échec
- si cette option est activée, des restrictions peuvent s'appliquer. Cependant, cela a été supprimé dans PHP 5.4. Si vous utilisez toujours une version qui prend en charge la mise à niveau en mode sans échec vers une version PHP toujours prise en charge .
- allow_url_fopen et allow_url_include
- cela s'applique uniquement à l'inclusion ou à l'ouverture de fichiers via un processus réseau tel que http: // pas lorsque vous essayez d'inclure des fichiers sur le système de fichiers local
- ceci peut être vérifié
ini_get("allow_url_include")
et réglé avecini_set("allow_url_include", "1")
Cas d'angle
Si aucune des solutions ci-dessus n'a permis de diagnostiquer le problème, voici quelques situations spéciales qui pourraient se produire:
1. L'inclusion d'une bibliothèque reposant sur le chemin d'inclusion
Il peut arriver que vous incluiez une bibliothèque, par exemple, le framework 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 peut se produire car le fichier que vous avez inclus (avec succès) a lui-même une instruction d'inclusion pour un autre fichier, et cette seconde instruction d'inclusion suppose que vous avez ajouté le chemin de cette bibliothèque au chemin d'inclusion.
Par exemple, le fichier de framework Zend mentionné précédemment pourrait avoir les éléments suivants:
include "Zend/Mail/Protocol/Exception.php"
qui n'est ni une inclusion par chemin relatif, ni par chemin absolu. Il suppose que le répertoire du framework Zend a été ajouté au chemin d'inclusion.
Dans un tel cas, la seule solution pratique est d'ajouter le répertoire à votre chemin d'inclusion.
2. SELinux
Si vous utilisez Linux à sécurité renforcée, cela peut ê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, exécutez la sestatus
commande dans un terminal. Si la commande n'existe pas, alors SELinux n'est pas sur votre système. S'il existe, il devrait vous dire s'il est appliqué ou non.
Pour vérifier si les politiques SELinux sont la cause du problème, vous pouvez essayer de la désactiver temporairement. Cependant, soyez prudent, car cela désactivera complètement la protection. Ne faites pas cela sur votre serveur de production.
setenforce 0
Si vous n'avez plus le problème avec SELinux désactivé, c'est la cause principale.
Pour le résoudre , vous devrez configurer SELinux en conséquence.
Les types de contexte suivants seront nécessaires:
httpd_sys_content_t
pour les fichiers que vous souhaitez que votre serveur puisse lire
httpd_sys_rw_content_t
pour les fichiers sur lesquels vous souhaitez un accès en lecture et en écriture
httpd_log_t
pour les fichiers journaux
httpd_cache_t
pour le répertoire cache
Par exemple, pour attribuer le httpd_sys_content_t
type de contexte au répertoire racine de votre site Web, exécutez:
semanage fcontext -a -t httpd_sys_content_t "/path/to/root(/.*)?"
restorecon -Rv /path/to/root
Si votre fichier se trouve dans un répertoire personnel, vous devrez également activer le httpd_enable_homedirs
booléen:
setsebool -P httpd_enable_homedirs 1
Dans tous les cas, il peut y avoir une variété de raisons pour lesquelles SELinux refuserait l'accès à un fichier, en fonction de vos politiques. Vous devrez donc vous renseigner à ce sujet. Voici un tutoriel spécifiquement sur la configuration de SELinux pour un serveur Web.
3. Symfony
Si vous utilisez Symfony et que vous rencontrez cette erreur lors du téléchargement sur un serveur, il se peut que le cache de l'application n'ait pas été réinitialisé, soit parce qu'il app/cache
a été téléchargé, soit parce que le cache n'a pas été effacé.
Vous pouvez tester et résoudre ce problème en exécutant la commande de console suivante:
cache:clear
4. Caractères non ACSII dans le fichier Zip
Apparemment, cette erreur peut également 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, tels que «é».
Une solution potentielle consiste à insérer le nom du fichier utf8_decode()
avant de créer le fichier cible.
Remerciements à Fran Cano pour avoir identifié et suggéré une solution à ce problème