是否有任何优雅的方法来检查文件是否包含使用include
/ include_once
/ require
/ require_once
或者页面是否实际直接加载?我正在尝试在创建它们时在类文件中设置测试文件.
我正在寻找类似于Python if __name__ == "__main__":
技术的东西.不设置全局变量或常量.
Jos*_*ser 20
引自:如何知道是否通过require_once()调用php脚本?
我正在寻找一种方法来确定文件是否已被包含或直接调用,所有这些都来自文件.在我的任务的某个时刻,我通过了这个线程.检查PHP手册中这个和其他网站和页面上的各种其他线程我得到了启发,并提出了这段代码:
if (basename(__FILE__) == basename($_SERVER["SCRIPT_FILENAME"])) {
echo "called directly";
} else {
echo "included/required";
}
Run Code Online (Sandbox Code Playgroud)
实质上,它会比较当前文件的名称(可以包含的文件的名称)是否与正在执行的文件相同.
图片来源:@Interwebs Cowboy
qwe*_*ymk 16
我很欣赏所有答案,但我不想在这里使用任何一个解决方案,所以我结合了你的想法并得到了这个:
<?php
// place this at the top of the file
if (count(get_included_files()) == 1) define ('TEST_SUITE', __FILE__);
// now I can even include bootstrap which will include other
// files with similar setups
require_once '../bootstrap.php'
// code ...
class Bar {
...
}
// code ...
if (defined('TEST_SUITE') && TEST_SUITE == __FILE__) {
// run test suite here
}
?>
Run Code Online (Sandbox Code Playgroud)
if (defined('FLAG_FROM_A_PARENT'))
// Works in all scenarios but I personally dislike this
if (__FILE__ == get_included_files()[0])
// Doesn't work with PHP prepend unless calling [1] instead.
if (__FILE__ == $_SERVER['DOCUMENT_ROOT'] . $_SERVER['SCRIPT_FILENAME'])
// May break on Windows due to mixed DIRECTORY_SEPARATOR
if (basename(__FILE__) == basename($_SERVER['SCRIPT_FILENAME']))
// Doesn't work with files with the same basename but different paths
if (realpath(__FILE__) == realpath($_SERVER['DOCUMENT_ROOT'].$_SERVER['SCRIPT_NAME']))
// Seems to do the trick as long as the file is under the document root.
Run Code Online (Sandbox Code Playgroud)
注意:在WAMP服务器上,虚拟主机有时会继承默认文档根设置,导致$ _SERVER ['DOCUMENT_ROOT']显示错误的路径.
他们没有办法将它们分开,include/include_once/require/require_once
但是php有,get_included_files
并且get_required_files
它是同一个东西,只返回所有包含文件的数组.如果它required
或它,它不会分开它included
.
例 a.php
include 'b.php';
include_once 'c.php';
require 'd.php';
var_dump(get_required_files());
Run Code Online (Sandbox Code Playgroud)
产量
array
0 => string '..\lab\stockoverflow\a.php' (length=46) <---- Returns current file
1 => string '..\lab\stockoverflow\b.php' (length=46)
2 => string '..\lab\stockoverflow\c.php' (length=46)
3 => string '..\lab\stockoverflow\d.php' (length=46)
Run Code Online (Sandbox Code Playgroud)
但你可以做点什么
$inc = new IncludeManager($file);
var_dump($inc->find("b.php")); // Check if a file is included
var_dump($inc->getFiles("require_once")); // Get All Required Once
Run Code Online (Sandbox Code Playgroud)
使用的类
class IncludeManager {
private $list = array();
private $tokens = array();
private $find;
private $file;
private $type = array(262 => "include",261 => "include_once",259 => "reguire",258 => "require_once");
function __construct($file) {
$this->file = $file;
$this->_parse();
}
private function _parse() {
$tokens = token_get_all(file_get_contents($this->file));
for($i = 0; $i < count($tokens); $i ++) {
if (count($tokens[$i]) == 3) {
if (array_key_exists($tokens[$i][0], $this->type)) {
$f = $tokens[$i + 1][0] == 371 ? $tokens[$i + 2][1] : $tokens[$i + 1][1];
$this->list[] = array("pos" => $i,"type" => $this->type[$tokens[$i][0]],"file" => trim($f, "\"\'"));
}
}
}
}
public function find($find) {
$finds = array_filter($this->list, function ($v) use($find) {
return $v['file'] == $find;
});
return empty($finds) ? false : $finds;
}
public function getList() {
return $this->list;
}
public function getFiles($type = null) {
$finds = array_filter($this->list, function ($v) use($type) {
return is_null($type) ? true : $type == $v['type'];
});
return empty($finds) ? false : $finds;
}
}
Run Code Online (Sandbox Code Playgroud)
<?php
if (__FILE__ == $_SERVER['SCRIPT_FILENAME'])
{
//file was navigated to directly
}
?>
Run Code Online (Sandbox Code Playgroud)
摘自 mgutt 对这里稍微不同的问题的回答。重要的是要注意,如果脚本是从命令行运行的,这将不起作用,但除此之外它的功能与 python 完全一样
if __name__ == '__main__':
Run Code Online (Sandbox Code Playgroud)
据我所知
get_included_files()
return array where 0 index mean first "included" file. Because direct run mean "include" in this terms, you can simple check first index for equality for __FILE__
:
if(get_included_files()[0] == __FILE__){
do_stuff();
}
Run Code Online (Sandbox Code Playgroud)
This can not work on PHP 4, because PHP 4 not add run file in this array.