包含的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";
?>
虽然$_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
过度使用时可能会引起明显的表现拖动。
最简单的方法:$_SERVER['SCRIPT_FILENAME']
会显示在原始文件叫做。
通用方式 - debug_backtrace()
将向您显示执行的所有先前步骤,其中将包括对require/include函数的调用。
$_SERVER['PHP_SELF']
还是应该指向原来的文件访问,或者你可以设置一个变量前需要,如:
$section = 'home';
require_once('header.php');
...
if ($section == 'home') {
...
}
debug_print_backtrace();
检查PHP实况
PHP跟踪,做了包括您在回溯文件。随着一点点的帮助功能,您可以获取到了最后包括命令的文件名:
/**
* 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?。
谢谢! :)能够找到声明的位置。 +1 rep – Killrawr 2013-06-03 22:18:17
提供了一个包含的文件的堆栈,按照它们包含的顺序,在我的情况下给了我所需的一切。
具体来说,如果您已包含的文件中调用,该文件本身的文件路径将会被返回堆栈中的最新的条目,这包括它上面的一个,等
需要注意的是文件只列出一次,所以如果多次包含同一个文件,只有第一个包含文件会出现在堆栈中。对于我的目的来说这不是一个问题,但它绝对意味着这在任何情况下都不起作用。
具体示例:假设文件'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找出谁是包括的。
伟大的第一个答案。 :) – 2013-09-20 21:06:12
如果你需要这个功能,你可能会有一些设计问题。我相信更好的组织你的代码这个功能是不需要的。 – vbence 2011-03-05 15:58:48
好的解决方案,对我来说非常适合。 – Black 2016-03-01 08:44:36
vbence从来不需要修改别人的杂乱和迷宫式的代码。它会在某一天发生:D非常感谢解决方案! – Kaddath 2017-06-02 14:08:02