检查是否包含或加载了文件

时间:2012-10-21 16:17:52

标签: php

使用include / include_once / require / require_once或者页面是否实际直接加载,是否有任何优雅的方法来检查文件是否包含在内?我正在尝试在创建它们时在类文件中设置一个测试文件。

我正在寻找类似于Python if __name__ == "__main__":技术的东西。不设置全局变量或常量。

12 个答案:

答案 0 :(得分:24)

您可以通过get_included_files执行此操作 - 返回包含所包含或必需文件名称的数组,并针对__FILE__进行验证

答案 1 :(得分:16)

引自:How to know if php script is called via require_once()?

  

我一直在寻找一种方法来确定文件是否已被直接包含或调用,所有这些都来自文件。在我的任务的某个时刻,我通过了这个线程。检查PHP手册中的这个和其他网站和页面上的各种其他线程我得到了启发并提出了这段代码:

if ( basename(__FILE__) == basename($_SERVER["SCRIPT_FILENAME"]) ) {   echo "called directly"; }


else {   echo "included/required" }
  

本质上,它会比较当前文件的名称(即   可以包含)与正在执行的文件相同。

信用:@Interwebs Cowboy

答案 2 :(得分:15)

我很感谢所有答案,但我不想在这里使用任何一个解决方案,所以我结合了你的想法并得到了这个:

<?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  
    }
?>

答案 3 :(得分:8)

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.

注意:在WAMP服务器上,虚拟主机有时会继承默认文档根设置,导致$_SERVER['DOCUMENT_ROOT']显示错误的路径。

答案 4 :(得分:5)

他们无法将它们分隔为include/include_once/require/require_once,但php有get_included_filesget_required_files这是相同的事情,只返回所有包含文件的数组。如果requiredincluded

,则不会将其分开

示例a.php

include 'b.php';
include_once 'c.php';
require 'd.php';
var_dump(get_required_files());

输出

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)

但你可以做类似

的事情
$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 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;
    }
}

答案 5 :(得分:2)

<?php
    if (__FILE__ == $_SERVER['SCRIPT_FILENAME'])
    {
        //file was navigated to directly
    }
?>

取自mgutt对一个稍微不同的问题here的回答。重要的是要注意,如果脚本是从命令行运行的,那么它不起作用,但除此之外它的功能与python一样

if __name__ == '__main__':

据我所知

答案 6 :(得分:1)

get_included_files()返回数组,其中0索引表示第一个“包含”文件。因为直接运行在这个术语中意味着“包含”,所以您可以简单地检查__FILE__的第一个索引是否相等:

if(get_included_files()[0] == __FILE__){
    do_stuff();
}

这不适用于PHP 4,因为PHP 4不会在此数组中添加运行文件。

答案 7 :(得分:1)

工作解决方案:

$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 !");
}

答案 8 :(得分:0)

我不认为get_included_files是完美的解决方案,如果你的主脚本在检查之前包含了一些其他脚本怎么办?我的建议是检查__FILE__是否等于realpath($argv[1])

<?php
require('phpunit/Autoload.php');

class MyTests extends PHPUnit_Framework_TestCase
{
    // blabla...
}

if (__FILE__ == realpath($argv[0])) {
    // run tests.
}

答案 9 :(得分:0)

当我浏览它时,我对此问题采取了类似的方法。我找到的解决方案是在include_once方法中根据需要加载每个文件。希望这会有所帮助。

<div class="course-flex-container">
  <div class="course-flex-row">
    <div>edit</div>
    <div>delete</div>
  </div>
  <div class="course-flex-row-2">
    <div>Read Chapter 1 to 3</div>
  </div>
  <div class="course-flex-row">
    <div>Blaw 3100</div>
    <div>Due Date: 6/29/2017</div>
  </div>
</div>

我建立了以下功能来检查加载的文件:

$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.
}

输出:

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>
  ";
}

答案 10 :(得分:0)

这是一个不同的想法。 只需在需要时添加文件即可。 在包含文件中,您可以决定是否需要包含内容:

Array to delete: CACTTGCCTCAATGTAATAT, TATCATTGCCCAATTTAAGT, CACTTGCCTCAATGATATAT, CTCTTCCCTCAATGATTTAA, CTCTTGCCTCAATGTTATAT, CTGTTGGCTCAATCATATAT, CTGATGCCTCATTGATATAT, GTCTTGCCTCATTGATAAAT, CACTTGCCTCAATGAAATTT

A single array in the array of array references: CTCTTGCCTCAATCATATAT, CTCTTGCCTCATTGATATAT, CTCTTGCCTCAATCATATAT, CACTTGCCTCAATGAAATTT, GTCTTGCCTCATTGATAAAT, CACTTGCCTCAATGTAATAT, CTCTTCCCTCAATGATTTAA, CACTTGCCTCAATGATATAT, CTCTTGCCTCATTGATATAT, CTCTTGCCTCAATGTTATAT, CTGATGCCTCATTGATATAT, CTGTTGGCTCAATCATATAT

A single array in the array of array references: CACTTGCCTCAATGTAATAT, TATCATTGCCCAATTTAAGT, CACTTGCCTCAATGATATAT, CTCTTCCCTCAATGATTTAA, CTCTTGCCTCAATGTTATAT, CTGTTGGCTCAATCATATAT, CTGATGCCTCATTGATATAT, GTCTTGCCTCATTGATAAAT, CACTTGCCTCAATGAAATTT
Both arrays match!

A single array in the array of array references: TATCATTGCCCAATTTAAGT, TTTCTTTGCCGAATATAAGT, TTTCTATGCGCAATTTAAGT, TATCTTAGCCCAATTTTTGT, TTTCTTTGCCCAATATATGT, TTTCTTTGGCCTATTTTTGT, TTTGTTTGGCCATTTTATGT, TTTCTTTGGCGAATTTATCT, TTTCATTGCCCAATTATTGT, TTTCTTTGCCCAAAATAAGT, CACTTGCCTCAATGTAATAT

A single array in the array of array references: TTTCTTTGCCCAATATATGT, TTTCTTTGCCGAATATAAGT, TTTCTATGCGCAATTTAAGT, TATCTTAGCCCAATTTTTGT, TTTCTTTGGCCTATTTTTGT, TTTGTTTGGCCATTTTATGT, TTTCTTTGGCGAATTTATCT, TTTCATTGCCCAATTATTGT, TATCATTGCCCAATTTAAGT, TTTCTTTGCCCAAAATAAGT, CTCTTGCCTCAATCATATAT

A single array in the array of array references after removing one: CTCTTGCCTCAATCATATAT, CTCTTGCCTCATTGATATAT, CTCTTGCCTCAATCATATAT, CACTTGCCTCAATGAAATTT, GTCTTGCCTCATTGATAAAT, CACTTGCCTCAATGTAATAT, CTCTTCCCTCAATGATTTAA, CACTTGCCTCAATGATATAT, CTCTTGCCTCATTGATATAT, CTCTTGCCTCAATGTTATAT, CTGATGCCTCATTGATATAT, CTGTTGGCTCAATCATATAT

A single array in the array of array references after removing one: TATCATTGCCCAATTTAAGT, TTTCTTTGCCGAATATAAGT, TTTCTATGCGCAATTTAAGT, TATCTTAGCCCAATTTTTGT, TTTCTTTGCCCAATATATGT, TTTCTTTGGCCTATTTTTGT, TTTGTTTGGCCATTTTATGT, TTTCTTTGGCGAATTTATCT, TTTCATTGCCCAATTATTGT, TTTCTTTGCCCAAAATAAGT, CACTTGCCTCAATGTAATAT

A single array in the array of array references after removing one: TTTCTTTGCCCAATATATGT, TTTCTTTGCCGAATATAAGT, TTTCTATGCGCAATTTAAGT, TATCTTAGCCCAATTTTTGT, TTTCTTTGGCCTATTTTTGT, TTTGTTTGGCCATTTTATGT, TTTCTTTGGCGAATTTATCT, TTTCATTGCCCAATTATTGT, TATCATTGCCCAATTTAAGT, TTTCTTTGCCCAAAATAAGT, CTCTTGCCTCAATCATATAT

答案 11 :(得分:-2)

太简单了.. 我做了这样的事情:

//code for file.php
if (!isset($file_included)){
   echo "It was loaded!";
} else {
  echo "It was included!";
}

//code for loader.php
//proves that atleast loader.php has loaded,
//not the file we targeted first..
$file_included = true;
include("../file.php");

就是这样......就像在python中一样简单。