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

您可以在附加功能的帮助下做到这一点。在示例中,我使用了 echo 而不是 require:

$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 回答
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 回答
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 回答