使PHP闭包函数对PHP 5.2是安全的


Making a PHP closure function safe for PHP 5.2

以下函数适用于PHP>5.3,但在旧版本中会出错。我如何修改它以使其5.2安全?

function _iniloader_get_dirs($dir) {
        $dirs = array_filter(scandir($dir), function ($item) use ($dir) {
            return (is_dir($dir.'/'.$item) && $item != "." && $item != "..");
        });
        // Use array_values to reset the array keys:
        return array_values($dirs);
}

5.2错误:

分析错误:语法错误,意外的T_FUNCTION。。。在…上2号线

你可以在没有闭包的情况下轻松完成,但你会失去一些优雅:

function _iniloader_get_dirs($dir) {
    $dirs = array();
    $entries = scandir($dir);
    foreach($entries as $item) {
        if($item === '.' || $item === '..') continue;
        if(!is_dir($dir.'/'.$item)) continue;
        $dirs[] = $item;
    }
    return $dirs;
}

通常是在PHP中模拟闭包的方法<5.3与create_function()有关,但由于本例中的use子句,我无法想出一种方法来做到这一点,而不做一些可怕的事情,包括在全局范围内跳跃变量。我可能遗漏了什么。

在任何情况下,这里有一些代码可以在不需要关闭的情况下做同样的事情:

function _iniloader_get_dirs($dir) {
    $dirs = array();
    foreach (scandir($dir) as $item) {
        if (is_dir($dir.'/'.$item) && !in_array($item, array('.', '..'))) {
            $dirs[] = $item;
        }
    }
    return $dirs;
}

您可以这样做(未经测试)。其想法是将$dir的值插入到函数的源中。

function _iniloader_get_dirs($dir) {
    $dirs = array_filter(scandir($dir),
        create_function('$item', '$dir = ''' . $dir . ''';' .
            'return (is_dir($dir."/".$item) && $item != "." && $item != "..");'));
    return array_values($dirs);
}

如果您多次调用此函数,请注意,因为每次调用create_function时,它都会在程序内存中创建一个新函数,该函数将永远保留,即使它与除变量之外的其他函数本质上相同。所以,如果你经常调用这个函数,那么程序就会充满伪函数,内存就会耗尽。