从include()获取调用文件名

Jon*_*and 8 php include include-path magic-constants

我想从包含的文件中获取包含另一个文件的文件的名称.

我知道还有就是__FILE__魔法恒定的,但这样做没有帮助,因为它返回的名称包含文件,而不是包括一个.

有没有办法做到这一点?或者由于PHP的解释方式是不可能的?

gna*_*nac 28

所以这个问题已经很老了,但我一直在寻找答案,离开这里后不满意,我遇到了$_SERVER['SCRIPT_FILENAME']; 当然,如果执行包含的php文件是一个网页,这是有效的.

这为您提供了服务器上"包含文件"的完整路径.例如/var/www/index.php.因此,如果您只想要文件名,例如index.php,则需要使用basename(),例如

basename($_SERVER['SCRIPT_FILENAME']);

因此,如果在index.php中,您有以下行:

<?php include("./somephp.php"); ?>

在somephp.php中你有

echo "this is the file that included me: " . basename($_SERVER['SCRIPT_FILENAME']);

你会得到

this is the file that included me: index.php

输出到浏览器.如果用户在没有明确地在URL中包含文件名的情况下访问您的文件,这也适用,例如,www.example.com而不是 www.example.com/index.php.


The*_*aot 6

明知用于包含文件的功能include,include_once,require并且require_once,也知道他们被保留在PHP的话,这意味着它是不可能使用相同的名称来声明用户功能,并根据韦奇伍德的想法使用的debug_backtrace,你可以实际工作从包含调用的文件中删除.

我们要做的是迭代回溯,直到我们找到最近对四个包含函数中的任何一个的调用,以及调用它的文件.以下代码演示了该技术:

function GetIncludingFile()
{
    $file = false;
    $backtrace =  debug_backtrace();
    $include_functions = array('include', 'include_once', 'require', 'require_once');
    for ($index = 0; $index < count($backtrace); $index++)
    {
        $function = $backtrace[$index]['function'];
        if (in_array($function, $include_functions))
        {
            $file = $backtrace[$index]['file'];
            break;
        }
    }
    return $file;
}
Run Code Online (Sandbox Code Playgroud)

上面的代码将返回最后一个包含发生的文件的绝对路径,如果没有包含它将返回false.请注意,该文件可能已包含在另一个文件中包含的文件中,上述功能仅适用于最深的包含.

通过简单的修改,您还可以获取最后包含的文件:

function GetIncludedFile()
{
    $file = false;
    $backtrace =  debug_backtrace();
    $include_functions = array('include', 'include_once', 'require', 'require_once');
    for ($index = 0; $index < count($backtrace); $index++)
    {
        $function = $backtrace[$index]['function'];
        if (in_array($function, $include_functions))
        {
            $file = $backtrace[$index - 1]['file'];
            break;
        }
    }
    return $file;
}
Run Code Online (Sandbox Code Playgroud)

意见

请注意,这__FILE__不是包含的文件,而是当前文件.例如:

文件A.php:

<?php
    function callme()
    {
        echo __FILE__;
    }
?>
Run Code Online (Sandbox Code Playgroud)

文件B.php:

<?php
    include('A.php');
    callme();
?>
Run Code Online (Sandbox Code Playgroud)

文件index.php:

<?php
    include('B.php');
?>
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,在文件B.php的上下文中,包含的文件是B.php(并且包含文件是index.php),但函数的输出callme是A.php的路径,因为__FILE__在A.php中.


另请注意,$_SERVER['SCRIPT_FILENAME']它将提供客户端请求的脚本的绝对路径.如果$_SERVER['SCRIPT_FILENAME'] == __FILE__这意味着当前文件是请求的文件,因此可能没有任何包含...

上面的方法检查当前文件是否是所请求的文件,但是如果它还没有包括在内(下面是如何包含所请求文件的示例).可以检查是否存在任何包含物的实际解决方案count(get_included_files()) == 1.


请求的文件可以是以下列方式包含的文件:

文件x.php

<?php
   $var = 'something';
   include('index.php');
?>
Run Code Online (Sandbox Code Playgroud)

文件index.php

<?php
    if (!isset($var))
    {
        include('x.php');
        exit;
    }
    echo 'something';
?>
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,文件index.php将包含x.php,然后x.php将包含index.php,之后index.php输出"something"并将控制权返回给x.php,x.php将控制返回到索引.php然后到达出口;

这表明即使index.php是请求的脚本,它也包含在另一个脚本中.


小智 5

我找不到简单的方法来掩盖这一点.但是如果包含一个对你真的很重要,你可以用一些全局变量和你自己的include函数来破解它.

例如

<?php                                                                            

    $g_including_files = array();                                                    

    function my_include($file) {                                                     
        $bt =  debug_backtrace();

        global $g_including_files;                                                   
        $g_including_files[basename($file)] = $bt[0]['file']; 
        return include($file);                                                                                                                                                                     
    } 
Run Code Online (Sandbox Code Playgroud)

可能对你有所帮助:)


eri*_*sco 5

这实际上只是 PHP 模板引擎所做的一个特例。考虑有这个功能:

function ScopedInclude($file, $params = array())
{
    extract($params);
    include $file;
}
Run Code Online (Sandbox Code Playgroud)

然后A.php可以C.php像这样包括:

<?php
// A.php
ScopedInclude('C.php', array('includerFile' => __FILE__));
Run Code Online (Sandbox Code Playgroud)

此外,B.php可以C.php毫无困难地包含相同的方式。

<?php
// B.php
ScopedInclude('C.php', array('includerFile' => __FILE__));
Run Code Online (Sandbox Code Playgroud)

C.php 可以通过查看 $params 数组来知道它的包含者。

<?php
// C.php
echo $includerFile;
Run Code Online (Sandbox Code Playgroud)