Solución:
Hay muchas razones por las que uno puede encontrarse con este error y, por lo tanto, una buena lista de verificación de lo que debe verificar primero ayuda considerablemente.
Consideremos que estamos solucionando problemas en la siguiente línea:
require "/path/to/file"
Lista de Verificación
1. Verifique que no haya errores tipográficos en la ruta del archivo
- o comprobar manualmente (comprobando visualmente la ruta)
-
o mover lo que sea llamado por
require*
oinclude*
a su propia variable, repítelo, cópielo e intente acceder a él desde una terminal:$path = "/path/to/file"; echo "Path : $path"; require "$path";
Luego, en una terminal:
cat
2. Verifique que la ruta del archivo sea correcta con respecto a las consideraciones de ruta relativa frente a absoluta.
- si comienza con una barra inclinada “/”, entonces 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
- por ejemplo, el directorio de su sitio web podría ser
- si no comienza con una barra inclinada, entonces se basa en la ruta de inclusión (ver más abajo) o la ruta es relativa. Si es relativo, PHP calculará en relación con la ruta del directorio de trabajo actual.
- por lo tanto, no es relativo a la ruta 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 las cosas, mientras sigue generando una ruta absoluta en tiempo de ejecución, tiene 2 opciones:
- usar
require __DIR__ . "/relative/path/from/current/file"
. los__DIR__
La constante mágica devuelve el directorio del archivo actual. -
definir un
SITE_ROOT
constante a ti mismo:- en la raíz del directorio de su sitio web, cree un archivo, p. ej.
config.php
-
en
config.php
, escribirdefine('SITE_ROOT', __DIR__);
-
en cada archivo en el que desee hacer referencia a la carpeta raíz del sitio, incluya
config.php
, y luego use elSITE_ROOT
constante donde quieras:require_once __DIR__."/../config.php"; ... require_once SITE_ROOT."/other/file.php";
- en la raíz del directorio de su sitio web, cree un archivo, p. ej.
Estas 2 prácticas también hacen que su aplicación sea más portátil porque no depende de 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
Puede ser 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 se está ejecutando el servidor, puede usar posix_getpwuid:
$user = posix_getpwuid(posix_geteuid());
var_dump($user);
Para averiguar los permisos en el archivo, escriba el siguiente comando en la terminal:
ls -l
y mira la notación simbólica del permiso
5. Verifique la configuración de PHP
Si nada de lo anterior funcionó, entonces el problema probablemente sea que algunas configuraciones de PHP le prohíben acceder a ese archivo.
Tres configuraciones podrían ser relevantes:
- open_basedir
- Si 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 se puede verificar 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 está activado, se pueden aplicar restricciones. Sin embargo, esto se ha eliminado en PHP 5.4. Si todavía tiene una versión que admite el modo seguro, actualice a una versión de PHP que aún sea 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 intenta incluir archivos en el sistema de archivos local
- esto se puede comprobar con
ini_get("allow_url_include")
y establecer conini_set("allow_url_include", "1")
Casos de esquina
Si nada de lo anterior permitió diagnosticar el problema, aquí hay algunas situaciones especiales que podrían suceder:
1. La inclusión de la biblioteca que se basa en la ruta de inclusión.
Puede suceder que incluyas una biblioteca, por ejemplo, el framework Zend, usando una ruta relativa o absoluta. Por ejemplo :
require "/usr/share/php/libzend-framework-php/Zend/Mail/Protocol/Imap.php"
Pero luego sigue recibiendo el mismo tipo de error.
Esto podría suceder porque el archivo que ha incluido (con éxito) tiene en sí mismo una declaración de inclusión para otro archivo, y esa segunda declaración de inclusió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 asume que el directorio del framework 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 Linux con seguridad mejorada, entonces podría ser la razón del problema, al denegar el acceso al archivo desde el servidor.
Para comprobar 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 comprobar si las políticas de SELinux son la razón para solucionar el problema, puede intentar apagarlo temporalmente. Sin embargo, tenga CUIDADO, ya que esto desactivará la protección por completo. No hagas esto en tu servidor de producción.
setenforce 0
Si ya no tiene el problema con SELinux desactivado, esta es la causa principal.
Para solucionarlo, deberá configurar SELinux en consecuencia.
Serán necesarios los siguientes tipos de contexto:
httpd_sys_content_t
para los archivos que desea que su servidor pueda leerhttpd_sys_rw_content_t
para archivos en los que desea acceso de lectura y escriturahttpd_log_t
para archivos de registrohttpd_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 que SELinux negaría el acceso a un archivo, dependiendo de sus políticas. Así que tendrás que investigar eso. Aquí hay un tutorial específicamente sobre cómo configurar SELinux para un servidor web.
3. Symfony
Si está utilizando Symfony y experimenta este error al cargar a un servidor, entonces puede ser que la caché de la aplicación no se haya restablecido, ya sea porque app/cache
se ha cargado o esa caché no se ha borrado.
Puede probar y solucionar este problema ejecutando el siguiente comando de consola:
cache:clear
4. Caracteres no ACSII dentro del archivo Zip
Aparentemente, este error también puede ocurrir al llamar zip->close()
cuando algunos archivos dentro del zip tienen caracteres que no son ASCII en su nombre de archivo, como “é”.
Una posible solución es envolver el nombre del archivo en utf8_decode()
antes de crear el archivo de destino.
Créditos a Fran Cano por identificar y sugerir una solución a este problema
Para agregar a la respuesta existente (realmente buena)
Software de alojamiento compartido
open_basedir
es uno que puede dejarlo perplejo porque se puede especificar en una configuración de servidor web. Si bien esto se soluciona fácilmente si ejecuta su propio servidor dedicado, existen algunos paquetes de software de alojamiento compartido (como Plesk, cPanel, etc.) que configurarán una directiva de configuración por dominio. Debido a que el software crea el archivo de configuración (es decir, httpd.conf
) no puede cambiar ese archivo directamente porque el software de alojamiento simplemente lo sobrescribirá cuando se reinicie.
Con Plesk, proporcionan un lugar para anular los httpd.conf
llamado vhost.conf
. Solo el administrador del servidor puede escribir este archivo. La configuración de Apache se parece a esto
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"
Haga que el administrador de su servidor consulte el manual del software de alojamiento y servidor web que utilizan.
Permisos de archivos
Es importante tener en cuenta que la ejecución de un archivo a través de su servidor web es muy diferente a la ejecución de una línea de comandos o un trabajo cron. La gran diferencia es que su servidor web tiene su propio usuario y permisos. Por razones de seguridad, ese usuario está bastante restringido. Apache, por ejemplo, es a menudo apache
, www-data
o httpd
(dependiendo de su servidor). Un trabajo cron o ejecución de CLI tiene los permisos que tiene el usuario que lo ejecuta (es decir, ejecutar un script PHP como root se ejecutará con permisos de root).
Muchas veces la gente resolverá un problema de permisos haciendo lo siguiente (ejemplo de Linux)
chmod 777 /path/to/file
Esta no es una idea inteligente, porque el archivo o directorio ahora se puede escribir en todo el mundo. Si usted es el propietario del servidor y es el único usuario, entonces esto no es un gran problema, pero si se encuentra en un entorno de alojamiento compartido, acaba de otorgar acceso a todos en su servidor.
Lo que debe hacer es determinar los usuarios que necesitan acceso y darles acceso solo a ellos. Una vez que sepa qué usuarios necesitan acceso, querrá asegurarse de que
-
Ese usuario es el propietario del archivo. y posiblemente el directorio principal (especialmente el directorio principal si desea escribir archivos). En la mayoría de los entornos de alojamiento compartido, esto no será un problema, porque su usuario debe poseer todos los archivos debajo de su raíz. A continuación se muestra un ejemplo de Linux
chown apache:apache /path/to/file
-
El usuario, y solo ese usuario, tiene acceso. En Linux, una buena práctica sería
chmod 600
(solo el propietario puede leer y escribir) ochmod 644
(el propietario puede escribir pero todos pueden leer)
Puede leer una discusión más extensa sobre los permisos y usuarios de Linux / Unix aquí
- Mira el exacto error
Mi código funcionó bien en todas las máquinas, pero solo en esta comenzó a dar problemas (que solía funcionar, supongo). Usé la ruta echo “document_root” para depurar y también miré de cerca el error, encontré esto
Advertencia: incluya (D: /MyProjects/testproject//functions/connections.php): fallo al abrir Stream:
Puede ver fácilmente dónde están los problemas. Los problemas son // antes de las funciones
$document_root = $_SERVER['DOCUMENT_ROOT'];
echo "root: $document_root";
include($document_root.'/functions/connections.php');
Así que simplemente elimine el lading / from include y debería funcionar bien. Lo interesante es que este comportamiento es diferente en diferentes versiones. Ejecuto el mismo código en Laptop, Macbook Pro y esta PC, todo funcionó bien hasta ahora. Espero que esto ayude a alguien.
- Copie más allá de la ubicación del archivo en el navegador para asegurarse de que el archivo exista. A veces, los archivos se eliminan inesperadamente (sucedió conmigo) y también fue el problema en mi caso.
Puedes añadir valor a nuestra información contribuyendo tu veteranía en los comentarios.