包含的PHP文件可以知道它包含在哪里吗?

时间:2011-03-05 15:45:50

标签: php

例如,

这是index.php

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

header.php可以知道它包含在index.php中吗?

- 编辑 -

我找到了解决方案:

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";
?>

6 个答案:

答案 0 :(得分:9)

虽然$_SERVER['PHP_SELF']将包含当前正在执行的脚本,但无法从包含的文件中确定哪个特定脚本导致了包含。

这意味着如果a.php包含b.php,其中包含c.php,则c.php将无法知道b.php是包含者。您可以获得的最好结果是a.php是当前正在执行的脚本。


编辑:是的,我的上述答案在技术上是错误的 - 你可以使用debug_backtrace找到调用者,即使没有函数,直到PHP 5.4,这将删除此功能。< / p>

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());

输出:

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
        )

)

因此,虽然这有效,但您可能不应该使用它。如果过度使用, debug_backtrace可能会显着降低性能。

答案 1 :(得分:5)

get_included_files()按照包含的顺序提供了一堆文件,在我的例子中给了我所需的一切。

具体来说,如果在已包含的文件中调用get_included_files(),则该文件自己的文件路径将是get_included_files()返回的堆栈上的最新条目,包含它的那个是以上,等等。

需要注意的是文件只列出一次,因此如果同一文件被包含多次,则只有第一个包含将显示在堆栈中。对于我的目的而言,这不是一个问题,但它绝对意味着这在所有情况下都不起作用。

具体示例:假设文件'test1.php'包含'test_include.php'。在浏览器中加载test1.php后,从'test_include.php'的角度看get_included_files()的结果如下(给出,我看到,我有一个auto_prepend文件,后者又加载了自动加载器)

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"
}

所以test_include.php只需要做一些array_pop'来弄清楚包含它的人。

答案 2 :(得分:3)

$_SERVER['PHP_SELF']仍应指向最初访问过的文件,或者您可以在require之前设置变量,例如:

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

...

if ($section == 'home') {
    ...
}

答案 3 :(得分:3)

PHP跟踪在回溯中为您执行包含的文件。使用一个小辅助函数,您可以获得具有最后一个include命令的文件名:

/**
 * 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.');
}

用法:

main.php:

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

sub.php:

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

请参阅回溯的相关用法:Caller function in PHP 5?

答案 4 :(得分:2)

debug_print_backtrace();

检查PHP文档

答案 5 :(得分:0)

Web服务器环境中最简单的方法:$_SERVER['SCRIPT_FILENAME']将显示被调用的原始文件。

通用方式 - debug_backtrace()将显示执行的所有先前步骤,其中包括对require / include功能的调用。