php 检查文件是否被包含或加载
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12999658/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Check if a file was included or loaded
提问by qwertymk
Is there any elegant way to check if a file was included by using include/include_once/require/require_onceor if the page was actually loaded directly? I'm trying to set up a testing file inside class files while I'm creating them.
是否有任何优雅的方式来检查通过使用是否包含一个文件include/ include_once/ require/require_once或如果页面实际上是直接加载?我正在尝试在创建类文件时在类文件中设置一个测试文件。
I'm looking for something similar to Python's if __name__ == "__main__":technique. Without setting globals or constants.
我正在寻找类似于 Pythonif __name__ == "__main__":技术的东西。无需设置全局变量或常量。
采纳答案by Joshua Kaiser
Quoted from: How to know if php script is called via require_once()?
引自:如何知道是否通过require_once()调用了php脚本?
I was looking for a way to determine if a file have been included or called directly, all from within the file. At some point in my quest I passed through this thread. Checking various other threads on this and other sites and pages from the PHP manual I got enlightened and came up with this piece of code:
我正在寻找一种方法来确定文件是否已被包含或直接调用,所有这些都来自文件。在我追求的某个时刻,我通过了这个线程。从 PHP 手册检查这个和其他网站和页面上的各种其他线程,我受到启发并想出了这段代码:
if (basename(__FILE__) == basename($_SERVER["SCRIPT_FILENAME"])) {
echo "called directly";
} else {
echo "included/required";
}
In essence it compares if the name of the current file (the one that could be included) is the same as the file that is beeing executed.
本质上,它比较当前文件的名称(可以包含的文件)是否与正在执行的文件相同。
Credit: @Interwebs Cowboy
信用:@Interwebs 牛仔
回答by NullPoiиteя
you can do this by get_included_files— Returns an array with the names of included or required files and validate against __FILE__
您可以通过get_included_files来执行此操作— 返回一个包含包含或所需文件名称的数组,并对其进行验证__FILE__
回答by qwertymk
I appreciate all the answers, but I didn't want to use any one's solution here, so I combined your ideas and got this:
我感谢所有的答案,但我不想在这里使用任何人的解决方案,所以我结合了你的想法并得到了这个:
<?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
}
?>
回答by tim
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.
Note: On WAMP Servers virtual-hosts sometimes inherit the default document root setting, causing $_SERVER['DOCUMENT_ROOT']to display wrong path.
注意:在 WAMP 服务器上,虚拟主机有时会继承默认的文档根设置,从而导致$_SERVER['DOCUMENT_ROOT']显示错误的路径。
回答by Baba
They is no way to separate them as include/include_once/require/require_oncebut php has get_included_filesand get_required_fileswhich is the same thing and only returns array of all included files. Its does not separate it if its requiredor included.
他们没有办法将它们分开,include/include_once/require/require_once但 php 有get_included_files,get_required_files这是同一件事,只返回所有包含文件的数组。如果它的required或 ,它不会将它分开included。
Example a.php
例子 a.php
include 'b.php';
include_once 'c.php';
require 'd.php';
var_dump(get_required_files());
Output
输出
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)
But you can do something like
但是你可以做类似的事情
$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
Class Used
使用的类
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;
}
}
回答by Josh R
<?php
if (__FILE__ == $_SERVER['SCRIPT_FILENAME'])
{
//file was navigated to directly
}
?>
Taken from mgutt's answer to a slightly different question here. It's important to note this doesn't work if the script is run from command line but other than that it functions exactly like python's
摘自 mgutt 对这里稍微不同的问题的回答。重要的是要注意,如果脚本是从命令行运行的,这将不起作用,但除此之外它的功能与 python 完全一样
if __name__ == '__main__':
as far as I can tell
据我所知
回答by ngmh
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__:
get_included_files()返回数组,其中 0 索引表示第一个“包含”文件。因为直接运行在这个术语中意味着“包含”,您可以简单地检查第一个索引是否相等__FILE__:
if(get_included_files()[0] == __FILE__){
do_stuff();
}
This can not work on PHP 4, because PHP 4 not add run file in this array.
这不能在 PHP 4 上运行,因为 PHP 4 没有在这个数组中添加运行文件。
回答by T.Todua
Working solution:
工作解决方案:
$target_file = '/home/path/folder/file.php'; // or use __FILE__
if ($x=function($e){return str_replace(array('\'), '/', $e);}) if(in_array( $x($target_file), array_map( $x , get_included_files() ) ) )
{
exit("Hello, already included !");
}
回答by Hardeen
I took a similar approach to this issue when I cam across it. The solution I found was to load each file as needed in an include_once method. Hope this helps.
当我遇到这个问题时,我对这个问题采取了类似的方法。我找到的解决方案是在 include_once 方法中根据需要加载每个文件。希望这可以帮助。
$FILES = get_included_files(); // Retrieves files included as array($FILE)
$FILE = __FILE__; // Set value of current file with absolute path
if(!in_array($FILE, $FILES)){ // Checks if file $FILE is in $FILES
include_once "PATH_TO_FILE"; // Includes file with include_once if $FILE is not found.
}
I have the following function established to check files loaded:
我建立了以下功能来检查加载的文件:
ARRAY_DUMP($FILES);
function ARRAY_DUMP($array){
echo "
<span style='font-size:12px;'>".date('h:i:s').":</span>
<pre style='font-size:12px;'>", print_r($array, 1), "</pre>
";
}
Output:
输出:
currentArray
(
[0] => /home/MY_DOMAIN/hardeen/index.php
[1] => /home/MY_DOMAIN/hardeen/core/construct.php
[2] => /home/MY_DOMAIN/hardeen/core/template.php
[3] => /home/MY_DOMAIN/hardeen/bin/tags.php
[4] => /home/MY_DOMAIN/hardeen/bin/systemFunction.php
)
回答by muz the axe
Here's a different idea. Just include the file whenever you need it. Inside the include file you can decide whether it needs to include the contents:
这是一个不同的想法。只需在需要时包含该文件。在包含文件中,您可以决定是否需要包含内容:
<?php
if (defined("SOME_UNIQUE_IDENTIFIER_FOR_THIS_FILE"))
return;
define("SOME_UNIQUE_IDENTIFIER_FOR_THIS_FILE", 1);
// Rest of code goes here

