Las funciones de incluir / requerir de PHP fallan para las rutas con "../" o "./"

1

Ingresé a mi servidor de desarrollo hoy para encontrar que PHP no pudo incluir algunos archivos con este mensaje E_WARNING:

Advertencia: include_once (../ file2.php) [function.include-once]: no se pudo abrir la secuencia: No existe dicho archivo o directorio en /var/www/web/some_directory_1/file1.php en línea lo que sea

Investigué un poco con nuestro administrador de sistemas y descubrimos que PHP solo falla cuando intenta incluir rutas de archivo con un '../' o './' en la ruta.

Supongamos que nuestra estructura de archivos se ve así:

/ var / www / web /
- index.php
- file2.php
- some_directory_1 /
---- file1.php
---- file3.php

Si file1.php quiere incluir file2.php, esto funcionará:

include_once('/var/www/web/file2.php');

Pero esto no lo hará:

include_once('../file2.php');

Ahora, espera un segundo ... ¡Sé lo que estás pensando! "Oh, su include_path es solo FUBAR". Bueno no exactamente.

Si haces esto en index.php, funciona:

include_once('some_directory_1/file1.php');

Y si haces esto en file1.php, también funciona:

include_once('file3.php');

Nuestro include_path está establecido en .:/usr/lib/php. Nada en el entorno del servidor ha cambiado en las últimas 24 horas (sin actualizaciones, sin software nuevo, sin cambios en las inclusiones, sin cambios en las configuraciones de Apache o PHP), yo y el administrador del sistema fueron las únicas personas que accedieron al servidor en el Las últimas 24 horas, y las inclusiones estaban funcionando bien ayer. Hemos agotado nuestra lista de posibles causas. ¿Alguna pista de lo que podría hacer que esto suceda?

Editar: Olvidé el mensaje de advertencia de PHP.

John Nicely
fuente
... Entonces, ¿por qué no agregas /var/www/web?
Ignacio Vazquez-Abrams
Verifique la salida de getcwd(), ¿tal vez algo está cambiando su directorio de trabajo? ¿Estás usando enlaces simbólicos? Los he visto confundir PHP.
Zoredache
@Ignacio 1) Utilizamos rutas relativas en cientos de lugares en todo el sitio. 2) En realidad no es una solución a nuestro problema, y ​​queremos saber por qué sucede esto, no solo solucionarlo. 3) También vendemos nuestro software de servidor, y los clientes pueden cambiar la ubicación del software. No podemos garantizar la ubicación absoluta de la ruta hasta después de cargar file1.php (file1.php establece las variables de configuración que usamos para cargar cualquier otro archivo en otro lugar).
John Nicely
@Zoredache getcwd () es el mismo que era antes y los únicos cambios que hice no afectan el cwd.
John Nicely
1
¿Hacer algo como esto? include_once(realpath(dirname(__FILE__)."/../file2.php"));
Zoredache

Respuestas:

2

La razón por la que tiene problemas es que la ruta relativa en un include / require siempre es relativa al script inicial , y el uso de una ruta relativa hace que php ignore el valor de include_path. Entonces, en su ejemplo, include_once('../file2.php');está buscando el archivo en el padre de index.php, suponiendo que index.php es el script inicial.

No estoy seguro de por qué cambiaría de repente. Pero, la solución es no usar rutas relativas, ya sea use include_path o use __DIR__/ dirname()como se sugiere en los comentarios.

xofer
fuente
Mira, el problema con eso es que hemos estado usando estas mismas rutas relativas durante 4 años sin ningún cambio ... Para repetir: no hemos actualizado PHP y no hemos cambiado la configuración.
John Nicely