Skip to content
Advertisement

How can I prevent double checks in this function?

Here is a code to search and return the existing files from the given directories:

<?php
function getDirContents($directories, &$results = array()) {

    $length = count($directories);
    for ($i = 0; $i < $length; $i++) {

        if(is_file($directories[$i])) {
            if(file_exists($directories[$i])) {
                $path = $directories[$i];
                $directory_path = basename($_SERVER['REQUEST_URI']);
                $results[] =  'https://' . $_SERVER['SERVER_NAME'] . str_replace($directory_path, "", $_SERVER['REQUEST_URI']) .$path;
            }

        } else {

            $files = array_diff(scandir($directories[$i]), array('..', '.'));
            foreach($files as $key => $value) {
                $path = $directories[$i].DIRECTORY_SEPARATOR.$value;
                if(is_dir($path)) {
                    getDirContents([$path], $results);
                } else {
                    $directory_path = basename($_SERVER['REQUEST_URI']);
                    $results[] =  'https://' . $_SERVER['SERVER_NAME'] . str_replace($directory_path, "", $_SERVER['REQUEST_URI']) .$path;
                }
            }

        }
        
    }

    return $results;
}

echo json_encode(getDirContents($_POST['directories']));

So you can pass an array of file addresses and directories and get what ever files inside those directories, Note if you pass a file address instead of a directory address the function checks if there is such a file and if there is it returns its address in the result .

The issue is for the directories it works fine but the files repeat twice in the result and for each file the function double checks this if statement in the code:

if(is_file($directories[$i]))

Here is a result of the function note that contemporary.mp3 and Japanese.mp3

has been re checked and added to the result.

enter image description here

How can I solve this?

Advertisement

Answer

If $directories contains both a directory and a file within that directory, you’ll add the file to the result for the filename and also when scanning the directory.

A simple fix is to check whether the filename is already in the result before adding it.

<?php
function getDirContents($directories, &$results = array()) {
    foreach ($directories as $name) {
        if(is_file($name)) {
            $path = $name;
            $directory_path = basename($_SERVER['REQUEST_URI']);
            $new_path = 'https://' . $_SERVER['SERVER_NAME'] . str_replace($directory_path, "", $_SERVER['REQUEST_URI']) .$path;
            if (!in_array($new_path, $results)) {
                $results[] =  $new_path;
            }
        } elseif (is_dir($name)) {
            $files = array_diff(scandir($name), array('..', '.'));
            foreach($files as $key => $value) {
                $path = $name.DIRECTORY_SEPARATOR.$value;
                if(is_dir($path)) {
                    getDirContents([$path], $results);
                } else {
                    $directory_path = basename($_SERVER['REQUEST_URI']);
                    $new_path = 'https://' . $_SERVER['SERVER_NAME'] . str_replace($directory_path, "", $_SERVER['REQUEST_URI']) .$path;
                    if (!in_array($new_path, $results)) {
                        $results[] =  $new_path;
                    }
                }
            }
        }
    }
    return $results;
}
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement