2011-03-05 132 views
15

例如,包含的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"; 
?> 
+1

如果你需要這個功能,你可能會有一些設計問題。我相信更好的組織你的代碼這個功能是不需要的。 – vbence 2011-03-05 15:58:48

+0

好的解決方案,對我來說非常適合。 – Black 2016-03-01 08:44:36

+0

vbence從來不需要修改別人的雜亂和迷宮式的代碼。它會在某一天發生:D非常感謝解決方案! – Kaddath 2017-06-02 14:08:02

回答

9

雖然$_SERVER['PHP_SELF']將包含目前執行腳本,無法從包含文件確定哪個特定腳本導致包含。

這意味着如果a.php包括b.php,其包括c.phpc.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過度使用時可能會引起明顯的表現拖動。

+1

這是我想要的答案。非常感謝你。 – webnat0 2011-03-05 15:53:32

+3

從技術上講,腳本可以通過使用debug_backtrace()找到它被包含在哪裏,但這不是可取的;) – 2011-03-05 15:54:49

+0

嗯,這是否在函數調用之外實際工作?稍後再檢查一下... – Charles 2011-03-05 16:05:55

0
在Web服務器環境

最簡單的方法:$_SERVER['SCRIPT_FILENAME']會顯示在原始文件叫做。

通用方式 - debug_backtrace()將向您顯示執行的所有先前步驟,其中將包括對require/include函數的調用。

3

$_SERVER['PHP_SELF']還是應該指向原來的文件訪問,或者你可以設置一個變量前需要,如:

$section = 'home'; 
require_once('header.php'); 

...

if ($section == 'home') { 
    ... 
} 
2
debug_print_backtrace(); 

檢查PHP實況

3

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?

+0

謝謝! :)能夠找到聲明的位置。 +1 rep – Killrawr 2013-06-03 22:18:17

4

​​提供了一個包含的文件的堆棧,按照它們包含的順序,在我的情況下給了我所需的一切。

具體來說,如果您已包含的文件中調用​​,該文件本身的文件路徑將會被​​返回堆棧中的最新的條目,這包括它上面的一個,等

需要注意的是文件只列出一次,所以如果多次包含同一個文件,只有第一個包含文件會出現在堆棧中。對於我的目的來說這不是一個問題,但它絕對意味着這在任何情況下都不起作用。

具體示例:假設文件'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找出誰是包括的。

+0

偉大的第一個答案。 :) – 2013-09-20 21:06:12

相關問題