簡體   English   中英

包含的PHP文件可以知道它包含在哪里嗎?

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM