3

これは少し特殊です。これが実際に可能だとは思いませんが、SOコミュニティには何度も何度も驚かされました。ここに行きます。

PHP で与えられます。次のスニペットがあります。

$path = 'path/to/file.php';
$buffer = call_user_func(function() use($path){
    ob_start();
    require $path;
    return ob_get_clean();
});

含まれpath/to/file.phpている場合は$path、そのスコープに含まれます。インクルードされたファイルのコンテキストでこの変数を使用できないようにする方法はありますか?

たとえば、unset()設定解除された変数の値が返された場合、次のことができます。

require unset($path);

しかし、もちろんそれはうまくいきません。


好奇心旺盛な人のために、インクルーダーから値を継承しないように$pathています。

「難読化によるセキュリティ」は私が考えたものです。のようなものを渡しますが$thisIsThePathToTheFileAndNobodyBetterUseThisName、それは少しばかげているようで、まだ確実ではありません。

継承する必要がある他の「予約済み」変数については、すでにextract()andを使用していunset()ます。

$buffer = call_user_func(function() use($path, $collection){
    extract($collection);
    unset($collection);
    ob_start();
    // ...

編集:

私が最終的に行ったこと:

$buffer = call_user_func(function() use(&$data, $registry){
    extract($registry, EXTR_SKIP);
    unset($registry);
    ob_start();
    // only $data and anything in $registry (but not $registry) are available
    require func_get_arg(0);
    return ob_get_clean();
}, $viewPath);

use()おそらく、変数を無名関数のスコープに渡すために を使用しているため、私の質問は少し誤解を招くものでした。引数を渡すことは、私が言及するのを怠ったオプションでした。

@hakre とuse()+についてfunc_get_args():

$var = 'foo';
$func = function() use($var){
    var_dump(func_get_args());
};
$func(1, 2, 3);

/* produces
array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
}
4

3 に答える 3

2

func_get_arg()従来の関数引数を使用する代わりに使用します。

$buffer = call_user_func(function() {
    ob_start();
    require func_get_arg(0);
    return ob_get_clean();
}, $path);
于 2011-07-27T05:37:37.523 に答える
2

これは、追加機能を使用して行うことができます。この例では、require の代わりに echo を使用しました。

$path = 'hello';

function valStore($value = null) {
    static $s = null;
    if ($value !== null)
        $s = $value;
    else
        return $s;
}

valStore($path);
unset($path); # and gone
echo valStore();
于 2011-07-27T05:30:05.787 に答える
1

次のようなものを使用できます。

$path = 'path/to/file.php';
function getPath() {
    global $path;
    $p = $path;
    unset($path);
    return $p;
}
$buffer = call_user_func(function() {
    ob_start();
    require getPath();
    return ob_get_clean();
});
于 2011-07-27T05:32:23.117 に答える