PHP scandir() but exclude certain folders

1.9k views Asked by At

I found this function below here on stackoverflow however, I am trying to avoid scanning any directory with the name includes.

$dir = $_SESSION['site'];
function getDirContents($dir, &$results = array()){
    $files = scandir($dir);
    foreach ($files as $key => $value) {
        $path = realpath($dir.DIRECTORY_SEPARATOR.$value);
        if (!is_dir($path)) {                   
           $results[] = $path;
        } else if (is_dir($path) && $value != "." && $value != ".." ) { 
            getDirContents($path, $results);
            $results[] = $path;
        }
    }
    return $results;
}

I have tried adding an additional && as follows:

} else if (is_dir($path) && $value != "." && $value != ".." && !strstr($path,"includes/")) {

However, this does not seem to be doing the trick.

2

There are 2 answers

0
Michal Przybylowicz On BEST ANSWER

Just remove trailing slash:

!strstr($path,"includes")) {
0
Drakes On

I am trying to avoid scanning any directory with the name "includes".

You could try replacing

$files = scandir($dir);

with

$files = preg_grep("/includes/i", scandir($dir), PREG_GREP_INVERT);

This will result in an array of $files which do not contain the string "includes" using preg_grep and inverted matching.

If set to PREG_GREP_INVERT, this function returns the elements of the input array that do not match the given pattern (ref).

As a bonus, you can easily customize the regular expression to add more excluded paths. Example:

"/includes|admin|hidden|temp|cache|^\./i"

This will also exclude directories that start with a ., so you can reduce some of your logic.


An alternative is

$files = preg_grep('/^((?!includes).)*$/i', scandir($dir));

This will result in an array of $files which do not contain the string "includes". It uses preg_grep and negative look-arounds to check for "includes", and if not found, that path is included in the final array.