有没有办法找出使用了哪个文件require_once?

Is there a way to find out which FILE used require_once?

假设我有以下情况:

File1.php:

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

File2.php:

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

init.php:

<?php
magic_function_which_tells_me_which_file_parsed_this_file();
...
?>

我知道这是不可能的,但是有没有办法从 init.php 中知道当前执行中哪个文件包含 init.php 它?

即使没有函数,您也可以使用 debug_backtrace 找到来电者:

test1.php

<?php
echo 'test1';
include 'test2.php';

test2.php

<?php
echo 'test2';
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
    )
)

无论如何,我不推荐使用它,因为它 过度使用时可能会明显拖累性能。

在 init.php 的顶部,您可以使用 debug_backtrace() 获取有关堆栈的信息。这将告诉您,除其他外,哪个文件包含当前文件,以及在哪一行。

这是回溯输出的示例。如果你把它放在一个函数中,你就会有另一层数据。如果您在文件本身中直接调用它,那么最顶层会告诉您哪个文件包含该文件。

array (size=2)
  0 => 
    array (size=3)
      'file' => string 'fileThatIncudedMe.php' (length=63)
      'line' => int 6
      'function' => string 'require_once' (length=12)

您可以将其包装成实用函数:

function whoIncludedThisFile() {
    $bt = debug_backtrace();
    $includedMe = false;
    while (count($bt) > 0) {
        $set = array_shift($bt);
        if (
            array_key_exists('function', $set) === true &&
            in_array($set['function'], array('require', 'require_once', 'include', 'include_once'))
        ){
            $includedMe = array('file'=>$set['file'], 'line'=>$set['line']);
            break;
        }
    }
    return $includedMe;
}

print_r(whoIncludedThisFile());
// Array ( [file] => topLevelFile.php [line] => 2 )

当然可以。用 debug_print_backtrace().

#0 require_once() called at [C:\xampp\htdocs\file2.php:3]

#1 require_once(C:\xampp\htdocs\file2.php) called at [C:\xampp\htdocs\file1.php:3]

这会告诉您 init.php 是从 file2.php 的第 3 行包含的。

您也可以尝试使用变量来实现这一点。 我们将其命名为 $parentFile:

$parentFile = basename(__FILE__);
require('some.file.here.php');

在some.file.here.php中:

if($parentFile == 'another.file.php')
    // do something;

我会补充一个答案 - 显然所有的功劳都归功于在我之前已经回答过这个问题的人。

我所做的是将 debug_backtrace 输出格式化为错误日志:

$debug = debug_backtrace(2 , 16);
error_log('-------------------------------' );
foreach ( $debug as $error ) {
     error_log( str_pad( $error['file' ], 120 ) . str_pad($error ['line'] , 8) . $error['function' ] );
}

结果将是每行一个文件,其中包含 table 方式的 (file,line,function)。