有没有办法找出使用require_once的文件?

时间:2022-04-07 09:54:13

Let's say I have the following situation:

假设我有以下情况:

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

I know this is a long-shot, but is there a way to know from within init.php which file included init.php it in the current execution?

我知道这是一个长镜头,但有没有办法从init.php中知道当前执行中哪个文件包含init.php?

5 个解决方案

#1


You are able to use debug_backtrace to find the caller even without functions:

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

test1.php

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

test2.php

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

Output

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

Anyways, I'd not recommend using it because it can be a noticeable performance drag when used excessively.

无论如何,我不推荐使用它,因为当过度使用时它可能是一个明显的性能阻力。

#2


Sure you can. With a debug_print_backtrace().

你当然可以。使用debug_print_backtrace()。

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

在[C:\ xampp \ htdocs \ file2.php:3]调用#0 require_once()

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

在[C:\ xampp \ htdocs \ file1.php:3]调用的#1 require_once(C:\ xampp \ htdocs \ file2.php)

This will tell you that init.php was included from file2.php on line 3.

这将告诉您init.php包含在第3行的file2.php中。

#3


At the top of init.php, you could use debug_backtrace() to get information about the stack. This will tell you, among other things, which file included the current file, and at what line.

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

This is a sample of the backtrace output. If you put this in a function, you'll have another layer of data. If you call it right in the file itself, then the top-most layer tells you what file included that one.

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

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

You could wrap this up into a utility function:

你可以将它包装成一个实用程序函数:

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 )

#4


You may also try to use a variable to achieve this. Let's name it $parentFile:

您也可以尝试使用变量来实现此目的。我们将它命名为$ parentFile:

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

And in some.file.here.php:

在some.file.here.php中:

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

#5


I will chip in with an answer - obviously all the credit goes to the guys that already answered this before me.

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

What I did was to format the debug_backtrace output to the error log:

我所做的是将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' ] );
}

The result will be one file per line containing (file,line,function) in a table manner.

结果将是每行一个文件,包含(文件,行,函数)表格方式。

#1


You are able to use debug_backtrace to find the caller even without functions:

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

test1.php

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

test2.php

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

Output

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

Anyways, I'd not recommend using it because it can be a noticeable performance drag when used excessively.

无论如何,我不推荐使用它,因为当过度使用时它可能是一个明显的性能阻力。

#2


Sure you can. With a debug_print_backtrace().

你当然可以。使用debug_print_backtrace()。

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

在[C:\ xampp \ htdocs \ file2.php:3]调用#0 require_once()

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

在[C:\ xampp \ htdocs \ file1.php:3]调用的#1 require_once(C:\ xampp \ htdocs \ file2.php)

This will tell you that init.php was included from file2.php on line 3.

这将告诉您init.php包含在第3行的file2.php中。

#3


At the top of init.php, you could use debug_backtrace() to get information about the stack. This will tell you, among other things, which file included the current file, and at what line.

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

This is a sample of the backtrace output. If you put this in a function, you'll have another layer of data. If you call it right in the file itself, then the top-most layer tells you what file included that one.

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

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

You could wrap this up into a utility function:

你可以将它包装成一个实用程序函数:

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 )

#4


You may also try to use a variable to achieve this. Let's name it $parentFile:

您也可以尝试使用变量来实现此目的。我们将它命名为$ parentFile:

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

And in some.file.here.php:

在some.file.here.php中:

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

#5


I will chip in with an answer - obviously all the credit goes to the guys that already answered this before me.

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

What I did was to format the debug_backtrace output to the error log:

我所做的是将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' ] );
}

The result will be one file per line containing (file,line,function) in a table manner.

结果将是每行一个文件,包含(文件,行,函数)表格方式。