2011-03-05 14 views
15

Por ejemplo,¿Puede un archivo PHP incluido saber de dónde se ha incluido?

Ésta es index.php

<? 
require_once('header.php'); 
?> 

Puede header.php saber que fue incluida por index.php?

--EDIT--

he encontrado una solución:

function backtrace_filename_includes($name){ 
    $backtrace_array=debug_backtrace(); 
    if (strpos($backtrace_array[1]['file'],$name)==false){ 
     return false; 
    }else{ 
     return true; 
    } 
} 

header.php

<? 
if (backtrace_filename_includes('index.php')) echo "index.php"; 
?> 
+1

Si necesita esta función, es probable que tenga algunos problemas de diseño. Estoy seguro de que con una mejor organización de su código, esta función nunca será necesaria. – vbence

+0

Buena solución, funciona perfecto para mí. – Black

+0

vbence nunca tuvo que modificar el código desordenado y laberíntico de otra persona, obviamente ... sucederá algún día: D ¡muchas gracias por la solución! – Kaddath

Respuesta

9

Mientras $_SERVER['PHP_SELF'] contendrá el momento de ejecutar script, no hay manera de determinar a partir de un archivo incluido qué script específico provocó el include.

Esto significa que si a.php incluye b.php, que incluye c.php, c.php no tendrán manera de saber que era el b.php Includer. Lo mejor que puede obtener es que a.php es el script que se está ejecutando actualmente.


Editar: Sí, mi respuesta anterior es técnicamente incorrecto - se puede utilizar debug_backtrace para encontrar la persona que llama, incluso sin funciones, hasta PHP 5.4, que elimina esta funcionalidad.

a.php:

<?php 
echo 'A'; 
include 'b.php'; 

b.php:

<?php 
echo 'B'; 
include 'c.php'; 

c.php:

<?php 
echo 'C'; 
print_r(debug_backtrace()); 

de salida:

ABCArray 
(
    [0] => Array 
     (
      [file] => /tmp/b.php 
      [line] => 3 
      [function] => include 
     ) 

    [1] => Array 
     (
      [file] => /tmp/a.php 
      [line] => 3 
      [args] => Array 
       (
        [0] => /tmp/b.php 
       ) 

      [function] => include 
     ) 

) 

Entonces, mientras esto funciona, probablemente no deberías usarlo. debug_backtrace puede ser un arrastre de rendimiento notable cuando se usa en exceso.

+1

Esta es la respuesta que quería. Muchas gracias. – webnat0

+3

Técnicamente, una secuencia de comandos podría averiguar dónde se ha incluido mediante el uso de debug_backtrace(), pero eso no es recomendable;) –

+0

Hm, ¿eso realmente funciona cuando está fuera de una llamada de función? Lo comprobaré en unos momentos ... – Charles

0

La manera más fácil en el entorno de servidor Web: $_SERVER['SCRIPT_FILENAME'] mostrará el archivo original que se llama.

manera universal - debug_backtrace() le mostrará todos los pasos previos de la ejecución, que incluirán llamadas para requerir/incluir funciones.

3

$_SERVER['PHP_SELF'] debe todavía señalar a presentar visitada originalmente, o se podría establecer una variable antes de requerir, por ejemplo:

$section = 'home'; 
require_once('header.php'); 

...

if ($section == 'home') { 
    ... 
} 
2
debug_print_backtrace(); 

Comprobar PHP docu

3

PHP un seguimiento del archivo que hace lo que incluye para que en el trazado inverso. Con una función de ayuda poco se puede obtener el nombre de archivo que tenía el último comando incluyen:

/** 
* get filename that included this file 
* 
* @return string filename 
*/ 
function include_by() { 
    $bt = debug_backtrace(0); 
    while ($b = array_shift($bt)) { 
     if (in_array($b['function'], array('require', 'require_once', 'include', 'include_once'), 1)) { 
      return $b['file']; 
     } 
    } 
    throw new BadFunctionCallException('Not an include.'); 
} 

Uso:

main.php:

<?php 
include('sub.php'); 

sub.php:

<?php 
echo basename(include_by()); # main.php 

Ver también un uso relacionado de la traza inversa: Caller function in PHP 5?.

+0

Gracias! :) fue capaz de encontrar dónde estaba la declaración. +1 rep – Killrawr

4

get_included_files() proporciona una pila de los archivos incluidos, en el orden en que están incluidos, que en mi caso me dio todo lo que necesitaba.

En concreto, si se llama a get_included_files() dentro de un archivo que se ha incluido, propio archivo de la ruta de ese archivo será la más reciente entrada en la pila devuelto por get_included_files(), la que incluyó que está por encima de eso, etc.

La advertencia es que los archivos solo se enumeran una vez, por lo que si el mismo archivo se incluye más de una vez, solo se mostrará la primera inclusión en la pila. Para mis propósitos eso no fue un problema, pero definitivamente significa que esto no funcionará en todos los casos.

Ejemplo específico: imagine que el archivo 'test1.php' incluye 'test_include.php'. El resultado de get_included_files() desde la perspectiva de 'test_include.php' después de cargar test1.php en el navegador es el siguiente (dado que, como puede ver, tengo un archivo auto_prepair, que a su vez carga un autocargador) .

array(4) { 
    [0]=> 
    string(21) "/www/auto_prepend.php" 
    [1]=> 
    string(19) "/www/autoloader.php" 
    [2]=> 
    string(14) "/www/test1.php" 
    [3]=> 
    string(21) "/www/test_include.php" 
} 

Así test_include.php sólo hay que hacer un poco de array_pop'ing de averiguar quién lo incluyó.

+0

Excelente primera respuesta. :) –

Cuestiones relacionadas