在PHP中找出调用我的函数的文件名

37

如何找出调用我的函数的脚本文件名?

例如:

function sthing() {
echo __FILE__; // echoes myself
echo __CALLER_FILE__; // echoes the file that called me
}

你能否提供更多关于为什么以及出于什么目的你需要这样的功能的信息?可能是因为你从错误的角度来解决问题。 - Gordon
举个例子:使用相对路径的 require 从根目录加载文件,即使您在子目录中调用 require。每次调用 require 都必须在前面加上 DIR 可以通过包装函数来隐藏,但是这样 DIR 将指向包装函数的目录,而不是调用者的目录。 - Lajos Mészáros
6个回答

46
一种解决方案是使用 debug_backtrace 函数:在回溯中,这种信息应该是存在的。
或者,正如 Gordon 在评论中指出的那样,您还可以使用debug_print_backtrace 如果只想输出该信息而不处理它。
例如,使用包含以下内容的 temp.php
<?php
include 'temp-2.php';
my_function();

同时,temp-2.php 文件中包含以下内容:

<?php
function my_function() {
    var_dump(debug_backtrace());
}


从我的浏览器调用temp.php(即第一个脚本)会得到以下输出:

array
  0 => 
    array
      'file' => string '/.../temp/temp.php' (length=46)
      'line' => int 5
      'function' => string 'my_function' (length=11)
      'args' => 
        array
          empty

我有一个名为"temp.php"的文件名,这是调用该函数的文件名。


当然,你需要进行更多的测试(特别是在函数不在“第一级”包含文件中,而是在另一个文件包含的文件中——不确定debug_backtrace是否能够帮助到你……);但这可能会帮助你获得第一个想法……


也许还可以在答案中加入 debug_print_backtrace()。 - Gordon
@Gordon:谢谢你的建议;我编辑了我的答案,加上了那个 :-) - Pascal MARTIN
好的答案。这使得从结尾开始搜索“调用”文件变得容易,只需查找第一个不同的文件即可... - Franz

17

试试这段代码:

$key = array_search(__FUNCTION__, array_column(debug_backtrace(), 'function'));
var_dump(debug_backtrace()[$key]['file']);

2
完美。按预期工作。 - Dovy
2
如果你的 PHP 没有包含 array_column,你可以使用这个 polyfill:https://dev59.com/questions/BF4c5IYBdhLWcg3w59qQ#27422723 - userlond

3
除了Pascal Martins的建议外,您可以安装PECL扩展APD并使用类似apd_callstack()的东西,这样可以查看调用堆栈(引用示例)。
// returns an array containing an array of arrays.

Each array appears to contain:
[0] = function name
[1] = filename that contains function
[2] = *calling* line number in *calling* file
[3] = An array which is usually empty

但由于这是一个 PECL 扩展,可能会干扰 Zend Optimizer,因此最好使用 debug_backtrace()。


2

这会打印出文件名:行号

function myFunction() {
  $backfiles = debug_backtrace();
  echo $backfiles[0]['file'] . ':' . $backfiles[0]['line'];
}

2

2行 - 完成:

$backfiles=debug_backtrace();
echo $file_called_from=$backfiles[0]['file']; // complete filepath

或者只裁剪文件名,添加以下内容
echo "<Br>";
echo basename($file_called_from); // for only the filename without the path

0

你可以将文件名作为参数传递:

function sthing($filename) {
  echo __FILE__; // echoes myself
  echo $filename; // echoes the file that called me
}

当您调用函数时,需要传递魔术常量FILE

sthing(__FILE__);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接