我想从包含的文件中获取包含另一个文件的文件的名称。
我知道有__FILE__
魔法常数,但这没有帮助,因为它返回包含文件的名称,而不是包含文件的名称。
有没有办法做到这一点?或者由于 PHP 的解释方式是不可能的?
我想从包含的文件中获取包含另一个文件的文件的名称。
我知道有__FILE__
魔法常数,但这没有帮助,因为它返回包含文件的名称,而不是包含文件的名称。
有没有办法做到这一点?或者由于 PHP 的解释方式是不可能的?
所以这个问题很老了,但我一直在寻找答案,离开这里后不满意,我遇到了$_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
.
知道用于包含文件的函数是include
, include_once
,require
和require_once
, 也知道它们是 PHP 中的保留字, 意味着不能声明同名的用户函数, 并且基于wedgwood 的使用思想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;
}
上面的代码将返回最后一次包含发生的文件的绝对路径,如果没有任何包含,它将返回 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;
}
请注意,__FILE__
不是包含文件,而是当前文件。例如:
文件 A.php:
<?php
function callme()
{
echo __FILE__;
}
?>
文件 B.php:
<?php
include('A.php');
callme();
?>
文件索引.php:
<?php
include('B.php');
?>
在上面的示例中,在文件 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');
?>
文件 index.php
<?php
if (!isset($var))
{
include('x.php');
exit;
}
echo 'something';
?>
在上面的例子中,文件 index.php 将包含 x.php,然后 x.php 将包含 index.php,然后 index.php 输出“something”并将控制权返回给 x.php,x.php 将控制权返回给 index .php 并到达退出;
这表明即使 index.php 是请求的脚本,它也被包含在另一个脚本中。
我找不到简单的方法来解决这个问题。但是如果 include 对你来说真的很重要,你可以用一些全局变量和你自己的 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);
}
可能对你有帮助:)
这实际上只是 PHP 模板引擎所做的一个特例。考虑具有此功能:
function ScopedInclude($file, $params = array())
{
extract($params);
include $file;
}
然后A.php
可以包括C.php
这样的:
<?php
// A.php
ScopedInclude('C.php', array('includerFile' => __FILE__));
此外,B.php
可以毫无困难地包括C.php
相同的方式。
<?php
// B.php
ScopedInclude('C.php', array('includerFile' => __FILE__));
C.php
可以通过查看 $params 数组来了解它的包含器。
<?php
// C.php
echo $includerFile;