PHP - Error al abrir la secuencia: no existe tal archivo o directorio

166

En los scripts PHP, ya sea llamando include(), require(), fopen(), o sus derivados, tales como include_once, require_onceo incluso, move_uploaded_file()uno a menudo se encuentra con un error o advertencia:

Error al abrir la secuencia: no existe tal archivo o directorio.

¿Cuál es un buen proceso para encontrar rápidamente la causa raíz del problema?

Vic Seedoubleyew
fuente
55
He limpiado los comentarios fuera de tema en esta publicación. Por favor, mantenga las discusiones meta en meta. Sin embargo, tenga en cuenta que la discusión de la viabilidad de las preguntas canónicas se ha hecho una y otra vez. Ver ejemplo aquí .
El fantasma de Madara
1
Tengo el mismo problema, la única solución que siempre funcionó es: -1 Ir al archivo para incluir, botón derecho, propiedades, copiar la ruta completa Por ejemplo: C: /......../ file.php 2- inclúyelo. En realidad, vi que esta pregunta está respondida, y la respuesta está validada, pero para mí en algunos casos no funcionó, hasta que encontré la forma descrita anteriormente.
Rshad
@Rash gracias por contribuir. Desafortunadamente, su solución es incorrecta, porque mencionará el nombre de ruta absoluto, y eso es incorrecto. La razón por la cual esto está mal es porque, en el momento en que copie su proyecto en otro lugar, o lo mueva dentro de su computadora, todo se romperá.
Vic Seedoubleyew

Respuestas:

259

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:

  1. uso require __DIR__ . "/relative/path/from/current/file". La __DIR__constante mágica devuelve el directorio del archivo actual.
  2. define una SITE_ROOTconstante 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.phpy luego use la SITE_ROOTconstante 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:

  1. 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
  2. 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 .
  3. 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 sestatuscomando 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_ttipo 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_homedirsbooleano:

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/cachese 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

Vic Seedoubleyew
fuente
44
Creo que mencionarlo selinuxpuede ser una buena idea aquí. al menos necesitará httpd_sys_content_t(directorios y archivos de solo lectura utilizados por Apache) permiso en los archivos incluidos.
bansi
Muchas gracias por la sugerencia. Como no estoy familiarizado con SELinux, leí un poco e intenté responder a este caso. Siéntase libre de enviar comentarios o sugerir algunas modificaciones si no es correcto. Gracias otra vez por el comentario !
Vic Seedoubleyew
chcones temporal y no sobrevivirá a restoreconun reinicio. puede que necesite usar semanagepara cambiar el contexto del archivo. Aquí hay un buen tutorial simple para el sitio web
bansi
Otra posibilidad para agregar: almacenamiento en caché realpath: lyte.id.au/2014/05/01/what-the-hell-php
chrishiestand
@chrishiestand muchas gracias! ¡Ese artículo es realmente interesante! ¿Recuerdas cuál fue el curso de los eventos que llevaron a ese error? ¿Fue que inicialmente el usuario no tenía acceso de lectura a un archivo, luego se modificó, pero el caché aún consideraba que no era legible, por lo que arrojó ese error al abrir el archivo?
Vic Seedoubleyew
16

Para agregar a la (realmente buena) respuesta existente

Software de alojamiento compartido

open_basedires uno que puede confundirlo porque puede especificarse 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 construye 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 el httpd.confllamado provisto vhost.conf. Solo el administrador del servidor puede escribir este archivo. La configuración de Apache se parece a esto

<Directory /var/www/vhosts/domain.com>
    <IfModule mod_php5.c>
        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"
    </IfModule>
</Directory>

Haga que el administrador de su servidor consulte el manual del software de alojamiento y servidor web que utilizan.

Permisos de archivo

Es importante tener en cuenta que la ejecución de un archivo a través de su servidor web es muy diferente de la ejecución de una línea de comando o trabajo cron. La gran diferencia es que su servidor web tiene sus propios usuarios y permisos. Por razones de seguridad, ese usuario está bastante restringido. Apache, por ejemplo, es a menudo apache, www-datao 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 las personas resolverán 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 posee el servidor y es el único usuario, entonces esto no es un gran problema, pero si está en un entorno de alojamiento compartido, acaba de dar acceso a todos los que están 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

  1. Ese usuario posee el 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, ya que 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
  2. 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) o chmod 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í

Machavity
fuente
7
  1. Mira el error exacto

Mi código funcionó bien en todas las máquinas, pero solo en este comenzó a dar problemas (supongo que solía funcionar). Se usó la ruta echo "document_root" para depurar y también se examinó de cerca el error, se encontró esto

Advertencia: include ( D: /MyProjects/testproject//functions/connections.php ): no se pudo abrir la transmisión:

Puedes 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 cargamento / incluir y debería funcionar bien. Lo interesante es que este comportamiento es diferente en diferentes versiones. Ejecuté el mismo código en la computadora portátil, Macbook Pro y esta PC, todo funcionó bien hasta ahora. Espero que esto ayude a alguien.

  1. Copie más allá de la ubicación del archivo en el navegador para asegurarse de que el archivo existe. A veces los archivos se eliminan inesperadamente (sucedió conmigo) y también fue el problema en mi caso.
Hammad Khan
fuente
¿Cómo es eso diferente del paso 1 de la lista de verificación a continuación?
Vic Seedoubleyew
Paso 2 una verificación adicional, no relacionada con el paso 1. Simplemente navegue a la ruta propuesta en el navegador y vea si ve el archivo allí (no en el explorador de Windows sino en el navegador).
Hammad Khan
2

Agregar script con parámetros de consulta

Ese fue mi caso. En realidad, enlaza con la pregunta # 4485874 , pero voy a explicarlo aquí en breve.
Cuando intenta path/to/script.php?parameter=valuesolicitar, PHP busca el archivo con nombre script.php?parameter=value, porque UNIX le permite tener rutas como esta.
Si realmente necesita para pasar algunos datos de script incluido, simplemente declare como $variable=...o $GLOBALS[]=...u otra forma que desee.

Paul Lynn
fuente
2

Acciones de samba

Si tiene un servidor de prueba de Linux y trabaja desde un cliente de Windows, el recurso compartido de Samba interfiere con el comando chmod . Entonces, incluso si usa:

chmod -R 777 myfolder

en el lado de Linux es totalmente posible que el Unix Group \ www-data todavía no tenga acceso de escritura. Una solución de trabajo si su recurso compartido está configurado es que los administradores de Windows están asignados a la raíz: desde Windows, abra los Permisos, desactive la Herencia de su carpeta con copia y luego otorgue acceso completo para www-data.

Stephan Brunker
fuente
1

Otra posible causa: cambiar el nombre y / o mover archivos mientras está en un editor de texto. Pasé por todos los pasos anteriores sin éxito hasta que eliminé el archivo que seguía arrojando este error y creé uno nuevo, que solucionó el problema.

zMeadz
fuente
1
si entiendo lo que quieres decir correctamente, esto habría sido solucionado al instante por la primera verificación en la lista
Vic Seedoubleyew
# 1 no es explícito sobre las posibles causas
zMeadz
Sí, pero no te importan las causas, te importa encontrar la manera de solucionar el problema. Más importante aún, el paso número 1 habría resuelto su problema
Vic Seedoubleyew