Il y a de nombreuses raisons pour lesquelles on peut rencontrer cette erreur et une bonne liste de ce qu'il faut vérifier en premier est donc très utile.
Considérons que nous sommes en train de dépanner la ligne suivante :
require "/path/to/file"
Liste de contrôle
1. Vérifiez l'absence de fautes de frappe dans le chemin du fichier
- soit vérifier manuellement (en contrôlant visuellement le chemin)
-
ou déplacer ce qui est appelé par require*
o include*
dans sa propre variable, faites un écho, copiez-le, et essayez d'y accéder depuis 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 au fichier est correct en ce qui concerne les considérations de chemin relatif et absolu.
- s'il commence par une barre oblique "/", il ne s'agit pas de la racine du dossier de votre site web (la racine du document), mais de 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, il s'appuie sur le chemin d'inclusion (voir ci-dessous) ou le chemin est relatif. S'il est relatif, alors PHP calculera relativement au chemin de l'objet le répertoire de travail actuel .
- donc, pas relative au chemin du Root de votre site web, ou au fichier où vous tapez
- pour cette raison, utilisez toujours des chemins de fichiers absolus
Meilleures pratiques :
Afin de rendre votre script robuste au cas où vous déplaceriez des choses, tout en générant un chemin absolu au moment de l'exécution, vous avez 2 options :
- utilice
require __DIR__ . "/relative/path/from/current/file"
. Le site __DIR__
constante magique renvoie le répertoire du fichier courant.
-
définir un SITE_ROOT
constant vous-même :
-
à la racine du répertoire de votre site web, créez un fichier, par ex. config.php
-
sur config.php
, écrivez
define('SITE_ROOT', __DIR__);
-
dans chaque fichier où vous voulez faire référence au dossier racine du site, incluez config.php
et ensuite utiliser le SITE_ROOT
constant où vous le souhaitez :
require_once __DIR__."/../config.php";
...
require_once SITE_ROOT."/other/file.php";
Ces deux pratiques rendent également votre application plus portable car elle ne dépend pas 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 relative ni de manière purement absolue, est de s'appuyer sur la fonction inclure le chemin . 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 devrez 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 l'utilisateur qui exécute le processus serveur (Apache ou PHP) n'ait tout simplement pas le droit de lire ou d'écrire dans ce fichier.
Pour vérifier sous quel utilisateur le serveur est exécuté, 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 regarder notation symbolique de la permission
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 de PHP lui interdisent d'accéder à ce fichier.
Trois paramètres pourraient être pertinents :
-
open_basedir
- Si cette option est activée, PHP ne pourra pas accéder à un fichier situé en dehors du répertoire spécifié (pas même via un lien symbolique).
- Cependant, le comportement par défaut est qu'il n'est pas défini, auquel cas il n'y a pas de restriction.
- Cela peut être vérifié soit en appelant
phpinfo()
ou en utilisant ini_get("open_basedir")
- Vous pouvez modifier ce 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 supporte le mode sans échec, mettez à jour votre version de PHP avec le mode sans échec. toujours soutenu .
-
allow_url_fopen et allow_url_include
- cela ne s'applique qu'à l'inclusion ou à l'ouverture de fichiers par le biais d'un processus réseau tel que http:// et non pas lorsqu'on essaie d'inclure des fichiers sur le système de fichiers local
- cela peut être vérifié avec
ini_get("allow_url_include")
et fixé avec ini_set("allow_url_include", "1")
Cas d'angle
Si aucune des méthodes ci-dessus n'a permis de diagnostiquer le problème, voici quelques situations particulières qui peuvent se produire :
1. L'inclusion de la bibliothèque s'appuyant 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 parce que le fichier que vous avez inclus (avec succès) a lui-même une déclaration d'inclusion pour un autre fichier, et cette deuxième déclaration d'inclusion suppose que vous avez ajouté le chemin de cette bibliothèque au chemin d'inclusion.
Par exemple, le fichier du framework Zend mentionné précédemment pourrait avoir l'include suivant :
include "Zend/Mail/Protocol/Exception.php"
qui n'est ni une inclusion par chemin relatif, ni par chemin absolu. Elle 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 à votre chemin d'inclusion.
2. SELinux
Si vous utilisez un système 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 le sestatus
dans un terminal. Si la commande n'existe pas, alors SELinux n'est pas présent sur votre système. Si elle existe, elle devrait vous indiquer si elle est appliquée ou non.
Pour vérifier si les politiques SELinux en sont la cause pour le problème, vous pouvez essayer de l'éteindre temporairement. Cependant, soyez PRUDENT, car cela désactivera entièrement la protection. Ne faites pas cela sur votre serveur de production.
setenforce 0
Si vous ne rencontrez plus le problème lorsque SELinux est désactivé, il s'agit de la cause première.
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 voulez que votre serveur puisse lire.
-
httpd_sys_rw_content_t
pour les fichiers sur lesquels vous voulez un 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 attribuer le httpd_sys_content_t
dans le 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 l'option d'accès à l'information. httpd_enable_homedirs
boolean :
setsebool -P httpd_enable_homedirs 1
Dans tous les cas, SELinux peut refuser l'accès à un fichier pour diverses raisons, en fonction de vos politiques. Vous devrez donc vous renseigner à ce sujet. Aquí est un tutoriel portant 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 vers un serveur, il est possible 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é vidé.
Vous pouvez tester et corriger ce problème en exécutant la commande console suivante :
cache:clear
4. Caractères non ACSII dans le fichier Zip
Apparemment, cette erreur peut également se produire en appelant zip->close()
lorsque certains fichiers du zip contiennent des caractères non ASCII dans leur nom de fichier, comme "é".
Une solution potentielle est d'envelopper le nom du fichier dans un fichier utf8_decode()
avant de créer le fichier cible.
Crédits pour Fran Cano pour avoir identifié et suggéré une solution à ce problème
5 votes
J'ai nettoyé les commentaires hors-sujet de ce post. Veuillez garder les discussions méta dans les méta. Cependant, veuillez noter que la discussion sur la viabilité des questions canoniques a été faite encore et encore et encore. Voir exemple aquí .
1 votes
J'ai le même problème, la seule solution qui a toujours fonctionné est la suivante : -1 Allez sur le fichier à inclure, cliquez à droite, propriétés, copiez le chemin complet. Par exemple : C:/......../file.php 2- Incluez-le. En fait, j'ai vu que cette question est répondue , et la réponse est validée , mais pour moi dans certains cas ne fonctionne pas , jusqu'à ce que je trouve la façon décrite ci-dessus .
0 votes
@Rash merci pour votre contribution. Malheureusement, votre solution est erronée, car elle mentionne le nom du chemin absolu, ce qui est faux. La raison pour laquelle c'est faux, c'est qu'au moment où vous copiez votre projet ailleurs, ou que vous le déplacez dans votre ordinateur, tout se casse.