Hay muchas razones por las cuales uno podría encontrarse con este error y, por lo tanto, una buena lista de verificación de qué verificar primero ayuda considerablemente.
Consideremos que estamos solucionando problemas en la siguiente línea:
require "/path/to/file"
Lista de Verificación
1. Verifique la ruta del archivo en busca de errores tipográficos
- ya sea verificar manualmente (verificando visualmente la ruta)
o mueva lo que sea llamado por require*
o include*
a su propia variable, repítalo, cópielo e intente acceder a él desde un terminal:
$path = "/path/to/file";
echo "Path : $path";
require "$path";
Luego, en una terminal:
cat <file path pasted>
2. Compruebe que la ruta del archivo es correcta con respecto a las consideraciones relativas frente a la ruta absoluta
- si comienza con una barra diagonal "/", no se refiere a la raíz de la carpeta de su sitio web (la raíz del documento), sino a la raíz de su servidor.
- por ejemplo, el directorio de su sitio web podría ser
/users/tony/htdocs
- si no comienza con una barra diagonal, entonces depende de la ruta de inclusión (ver más abajo) o la ruta es relativa. Si es relativo, entonces PHP calculará relativamente la ruta del directorio de trabajo actual .
- por lo tanto, no es relativo a la ruta de acceso de la raíz de su sitio web, o al archivo donde está escribiendo
- por esa razón, siempre use rutas de archivo absolutas
Mejores prácticas :
Para hacer que su script sea robusto en caso de que mueva cosas, mientras genera una ruta absoluta en tiempo de ejecución, tiene 2 opciones:
- uso
require __DIR__ . "/relative/path/from/current/file"
. La __DIR__
constante mágica devuelve el directorio del archivo actual.
define una SITE_ROOT
constante tu mismo:
- en la raíz del directorio de su sitio web, cree un archivo, por ejemplo
config.php
adentro config.php
, escribe
define('SITE_ROOT', __DIR__);
en cada archivo donde desee hacer referencia a la carpeta raíz del sitio, incluya config.php
y luego use la SITE_ROOT
constante donde desee:
require_once __DIR__."/../config.php";
...
require_once SITE_ROOT."/other/file.php";
Estas 2 prácticas también hacen que su aplicación sea más portátil porque no se basa en configuraciones ini como la ruta de inclusión.
3. Verifique su ruta de inclusión
Otra forma de incluir archivos, ni relativa ni puramente absoluta, es confiar en la ruta de inclusión . Este suele ser el caso de bibliotecas o marcos como el marco Zend.
Tal inclusión se verá así:
include "Zend/Mail/Protocol/Imap.php"
En ese caso, querrá asegurarse de que la carpeta donde está "Zend" sea parte de la ruta de inclusión.
Puede verificar la ruta de inclusión con:
echo get_include_path();
Puede agregarle una carpeta con:
set_include_path(get_include_path().":"."/path/to/new/folder");
4. Verifique que su servidor tenga acceso a ese archivo
Es posible que, en conjunto, el usuario que ejecuta el proceso del servidor (Apache o PHP) simplemente no tenga permiso para leer o escribir en ese archivo.
Para verificar con qué usuario está ejecutando el servidor, puede usar posix_getpwuid :
$user = posix_getpwuid(posix_geteuid());
var_dump($user);
Para conocer los permisos en el archivo, escriba el siguiente comando en el terminal:
ls -l <path/to/file>
y mira el permiso de notación simbólica
5. Compruebe la configuración de PHP
Si ninguno de los anteriores funcionó, entonces el problema es probablemente que algunas configuraciones de PHP le prohíben acceder a ese archivo.
Tres configuraciones podrían ser relevantes:
- open_basedir
- Si esto está configurado, PHP no podrá acceder a ningún archivo fuera del directorio especificado (ni siquiera a través de un enlace simbólico).
- Sin embargo, el comportamiento predeterminado es que no se establezca, en cuyo caso no hay restricción
- Esto puede verificarse llamando
phpinfo()
o usandoini_get("open_basedir")
- Puede cambiar la configuración editando su archivo php.ini o su archivo httpd.conf
- modo seguro
- si esto está activado, podrían aplicarse restricciones. Sin embargo, esto se ha eliminado en PHP 5.4. Si todavía está en una versión que admite la actualización en modo seguro a una versión de PHP que todavía es compatible .
- allow_url_fopen y allow_url_include
- esto se aplica solo a la inclusión o apertura de archivos a través de un proceso de red como http: // no cuando se trata de incluir archivos en el sistema de archivos local
- esto se puede verificar
ini_get("allow_url_include")
y configurar conini_set("allow_url_include", "1")
Casos de esquina
Si nada de lo anterior habilitado para diagnosticar el problema, aquí hay algunas situaciones especiales que podrían suceder:
1. La inclusión de la biblioteca basándose en la ruta de inclusión
Puede suceder que incluya una biblioteca, por ejemplo, el marco Zend, utilizando una ruta relativa o absoluta. Por ejemplo :
require "/usr/share/php/libzend-framework-php/Zend/Mail/Protocol/Imap.php"
Pero aún así obtienes el mismo tipo de error.
Esto podría suceder porque el archivo que ha incluido (con éxito) tiene una declaración de inclusión para otro archivo, y esa segunda declaración de asunción asume que ha agregado la ruta de esa biblioteca a la ruta de inclusión.
Por ejemplo, el archivo de marco Zend mencionado anteriormente podría incluir lo siguiente:
include "Zend/Mail/Protocol/Exception.php"
que no es una inclusión por ruta relativa, ni por ruta absoluta. Se supone que el directorio del marco Zend se ha agregado a la ruta de inclusión.
En tal caso, la única solución práctica es agregar el directorio a su ruta de inclusión.
2. SELinux
Si está ejecutando Security-Enhanced Linux, entonces podría ser la razón del problema, al negar el acceso al archivo desde el servidor.
Para verificar si SELinux está habilitado en su sistema, ejecute el sestatus
comando en una terminal. Si el comando no existe, entonces SELinux no está en su sistema. Si existe, entonces debería decirle si se aplica o no.
Para verificar si las políticas de SELinux son la razón del problema, puede intentar desactivarlo temporalmente. Sin embargo, tenga cuidado, ya que esto deshabilitará la protección por completo. No haga esto en su servidor de producción.
setenforce 0
Si ya no tiene el problema con SELinux apagado, esta es la causa raíz.
Para resolverlo , deberá configurar SELinux en consecuencia.
Los siguientes tipos de contexto serán necesarios:
httpd_sys_content_t
para los archivos que desea que su servidor pueda leer
httpd_sys_rw_content_t
para archivos en los que desea acceso de lectura y escritura
httpd_log_t
para archivos de registro
httpd_cache_t
para el directorio de caché
Por ejemplo, para asignar el httpd_sys_content_t
tipo de contexto al directorio raíz de su sitio web, ejecute:
semanage fcontext -a -t httpd_sys_content_t "/path/to/root(/.*)?"
restorecon -Rv /path/to/root
Si su archivo está en un directorio de inicio, también deberá activar el httpd_enable_homedirs
booleano:
setsebool -P httpd_enable_homedirs 1
En cualquier caso, podría haber una variedad de razones por las cuales SELinux negaría el acceso a un archivo, dependiendo de sus políticas. Entonces tendrá que investigar sobre eso. Aquí hay un tutorial específicamente sobre la configuración de SELinux para un servidor web.
3. Symfony
Si está utilizando Symfony y experimenta este error al cargar en un servidor, puede ser que la memoria caché de la aplicación no se haya restablecido, ya sea porque app/cache
se cargó o porque la memoria caché no se ha borrado.
Puede probar y solucionar esto ejecutando el siguiente comando de consola:
cache:clear
4. Caracteres no ACSII dentro del archivo Zip
Aparentemente, este error puede ocurrir también al llamar zip->close()
cuando algunos archivos dentro del zip tienen caracteres no ASCII en su nombre de archivo, como "é".
Una posible solución es envolver el nombre del archivo utf8_decode()
antes de crear el archivo de destino.
Créditos a Fran Cano por identificar y sugerir una solución a este problema