[英]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.