56

// include/を使用してファイルが含まれているかどうか、またはページが実際に直接ロードされているかどうかを確認するための洗練された方法はありますか?クラスファイルを作成しているときに、クラスファイル内にテストファイルを設定しようとしています。include_oncerequirerequire_once

if __name__ == "__main__":Pythonの手法に似たものを探しています。グローバルまたは定数を設定せずに。

4

12 に答える 12

33

引用元:phpスクリプトがrequire_once()を介して呼び出されているかどうかを知る方法は?

私は、ファイルがすべてファイル内から含まれているか、直接呼び出されているかを判断する方法を探していました。私の探求のある時点で、私はこのスレッドを通過しました。このサイトや他のサイトのさまざまなスレッドやPHPマニュアルのページを確認して、私は悟りを開いて次のコードを思いつきました。

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

本質的には、現在のファイル(含めることができるファイル)の名前が実行中のファイルと同じであるかどうかを比較します。

クレジット:@Interwebsカウボーイ

于 2012-10-21T16:29:14.523 に答える
26

get_included_filesでこれを行うことができます—含まれているファイルまたは必要なファイルの名前を含む配列を返し、に対して検証します__FILE__

于 2012-10-21T16:19:54.627 に答える
18

私はすべての答えに感謝しますが、ここでは誰の解決策も使いたくなかったので、あなたのアイデアを組み合わせてこれを手に入れました:

<?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  
    }
?>
于 2012-10-21T17:26:30.823 に答える
13
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['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['SCRIPT_FILENAME']))
// Seems to do the trick as long as document root is properly configured

注:WAMPサーバーでは、仮想ホストがデフォルトのドキュメントルート設定を継承し、$_SERVER['DOCUMENT_ROOT']間違ったパスを表示することがあります。

于 2014-01-05T17:44:23.847 に答える
6
<?php
    if (__FILE__ == $_SERVER['SCRIPT_FILENAME'])
    {
        //file was navigated to directly
    }
?>

ここで少し異なる質問に対するmguttの回答から引用。スクリプトがコマンドラインから実行される場合、これは機能しないことに注意することが重要ですが、それ以外は、Pythonとまったく同じように機能します。

if __name__ == '__main__':

私の知る限り

于 2016-01-06T12:34:03.073 に答える
5

それらを分離する方法はありません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());

出力

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;
    }
}
于 2012-10-21T16:23:16.837 に答える
5

get_included_files()配列を返します。0インデックスは最初の「インクルード」ファイルを意味します。この用語では、直接実行は「含める」ことを意味するため、最初のインデックスが等しいかどうかを簡単に確認できます__FILE__

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

PHP 4はこの配列に実行ファイルを追加しないため、これはPHP4では機能しません。

于 2017-09-09T12:39:46.063 に答える
2

これは別の考えです。必要なときにいつでもファイルを含めるだけです。インクルードファイル内で、コンテンツをインクルードする必要があるかどうかを判断できます。

<?php
if (defined("SOME_UNIQUE_IDENTIFIER_FOR_THIS_FILE"))
    return;
define("SOME_UNIQUE_IDENTIFIER_FOR_THIS_FILE", 1);

// Rest of code goes here
于 2018-08-19T04:17:17.923 に答える
2

実用的な解決策:

$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 !");
}
于 2018-09-23T14:58:24.677 に答える
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.
}
于 2014-01-02T02:59:25.023 に答える
0

私はこの問題に出くわしたときに、この問題に対して同様のアプローチを取りました。私が見つけた解決策は、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.
}

ロードされたファイルをチェックするために、次の関数を確立しました。

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

出力:

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
)
于 2017-06-30T17:10:11.727 に答える
-3

それはとても簡単です..私はこのようなものを作りました:

//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のように簡単です。

于 2016-03-13T23:29:51.610 に答える