2010-03-13 10 views
8

Es muy extraño, ¿alguien ha resuelto alguna vez una conclusión?¿Qué directorios verifica PHP cuando incluyen una ruta relativa con include()?

A veces también comprueba el directorio del archivo incluido.

Pero a veces no.

D: \ test \ 1.php

<?php 

include('sub\2.php'); 

D: \ test \ 2.PHP

<?php 

include('3.php'); 

Dónde 3.php se encuentra en el mismo directorio que 2.php.

Los trabajos anteriores, pero ¿por qué? El directorio actual debe ser D:\test, pero aún se pueden encontrar 3.php, que está en D:\test\sub

Más historia (última)

Sobre una hace años me encontré con este problema, y ​​luego terminé arreglado con el hardcoding, como a continuación:

Common.php:

if (file_exists("../../../Common/PHP/Config.inc")) 
    include('../../../Common/PHP/Config.inc'); 

if (file_exists("../../Common/PHP/Config.inc")) 
    include('../../Common/PHP/Config.inc'); 

if (file_exists("../Common/PHP/Config.inc")) 
    include('../Common/PHP/Config.inc'); 

if (file_exists("Common/PHP/Config.inc")) 
    include('Common/PHP/Config.inc'); 

Dónde Config.inc está en el mismo directorio que Common.php

+1

¡Buena pregunta! Puedo confirmar esto en Windows y Linux. No tengo idea de por qué es esto. –

+0

Con respecto a su último ejemplo, si "Config.inc" está en el mismo directorio que "Common.php", esto podría simplificarse para 'include (dirname (__ FILE __). '/ Config.inc');' - esto siempre trabajo, independientemente de 'include_path' y del archivo" Common.php "incluido en. Si no existe la posibilidad de que se encuentre "Config.inc" en el 'include_path' (en el que a menudo se incluye el directorio actual), entonces simplemente podría llamar' include 'Config.inc'; ', aunque esto posiblemente sea menos eficiente ya que el 'include_path' se busca primero (que falla). – MrWhite

+0

En su primer ejemplo, supongo que "D: \ test \ 2.php" debería ser "D: \ test \ sub \ 2.php"? (De lo contrario, 'include ('sub \ 2.php');' nunca funcionaría.) – MrWhite

Respuesta

1

Se comprueba en la ruta actual, y los directorios listados en include_path.

Puede ejecutar un phpinfo() para ver su ruta de inclusión.

+0

Esto no explica el problema que describí :( – user198729

+0

@user, que yo sepa, eso es todo.Por favor, muestre algunos ejemplos de cuándo se cargan los archivos y cuándo no. –

+0

Will 'getcwd()' cambia durante una solicitud si no la cambiamos explícitamente (como 'chdir()'). Voy a dar un ejemplo pronto. – user198729

1

veces directorio del archivo incluido ser current working directory ya veces no
directorio actual se puede comprobar con getcwd()

+0

Hola, he actualizado mi pregunta, eche un vistazo :) – user198729

2

Si se echa un vistazo al código fuente de PHP en el principal/fopen_wrappers.c encontrará

/* check in calling scripts' current working directory as a fall back case 
    */ 
    if (zend_is_executing(TSRMLS_C)) { 
     char *exec_fname = zend_get_executed_filename(TSRMLS_C); 
     int exec_fname_length = strlen(exec_fname); 

     while ((--exec_fname_length >= 0) && !IS_SLASH(exec_fname[exec_fname_length])); 
     if (exec_fname && exec_fname[0] != '[' && 
      exec_fname_length > 0 && 
      exec_fname_length + 1 + filename_length + 1 < MAXPATHLEN) { 
      memcpy(trypath, exec_fname, exec_fname_length + 1); 
      memcpy(trypath+exec_fname_length + 1, filename, filename_length+1); 
      actual_path = trypath; 

Esto parece ejecutarse incondicionalmente y por lo tanto siempre hará un archivo en la misma ruta que el script de inclusión/apertura de archivo accesible ... como la última opción después de todas las posibilidades especificadas en include_path. Y solo si no define una ruta relativa o absoluta en include().

+0

Parece que no entiendo este código, ¿hay alguna pista de por qué a veces no comprueba el directorio del archivo incluido? – user198729

+0

Para '3.php' primero prueba todas las ubicaciones incluidas en include \ _path. Una ruta relativa dada allí, p. 'include_path =.; ..; lalala' sería relativo al directorio de trabajo actual (que no es modificado por include()). Solo la última opción (adicional) es buscar en el mismo directorio en el que está el archivo incluido. "Toma" el primer '3.php' que puede encontrar. ¿Ese es tu problema: php toma otro 3.php como es de esperar? Sus otras preguntas parecen indicar que ... – VolkerK

+0

Mi problema es que a veces no encontrará 3.php, pero no puedo reproducirlo fácilmente. Pero está en el mismo directorio en el que está incluido el archivo. Quizás cuando ' include' está en una función/método, supongo ... – user198729