Yarin
Yarin

Reputation: 183509

Making a PHP closure function safe for PHP 5.2

The following function works in PHP > 5.3 but errors out in older versions. How can I modify this to make it 5.2 safe?

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 error:

Parse error: syntax error, unexpected T_FUNCTION ... on line 2

Upvotes: 3

Views: 778

Answers (3)

newacct
newacct

Reputation: 122429

You can do it like this (untested). The idea is to insert the value of $dir into the source of the function.

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

Beware if you call this function a lot, because every time create_function is called, it creates a new function in the program memory that stays forever, even if it is essentially the same as other functions except a variable. So if you call this a lot then the program will be filled with dummy functions and run out of memory.

Upvotes: 0

DaveRandom
DaveRandom

Reputation: 88647

Normally the way to mimic closures in PHP<5.3 is with create_function() but because of the use clause in this case, I can't come up with a way to do it without doing something horrible involving bouncing variables through the global scope. There may be something I'm missing.

In any case, here is some code that will do the same thing without requiring a closure:

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

Upvotes: 2

DerVO
DerVO

Reputation: 3679

You can easily do it w/o the closure, but you will lose some elegance:

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

Upvotes: 3

Related Questions