繁体   English   中英

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

[英]Can an included PHP file know where it was included from?

例如,

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

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

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


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

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可能会引起明显的性能拖累。

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'ing就可以找出包含它的人。

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

请参阅回溯的相关用法: PHP 5中的调用函数?

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

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

...

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

检查PHP文档

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM