13

This is the starting portion of my code to list files in a directory:

$files = scandir($dir); 
$array = array(); 
foreach($files as $file)
{
    if($file != '.' && $file != '..' && !is_dir($file)){
          ....

I'm trying to list all files in a directory without listing subfolders. The code is working, but showing both files and folders. I added !is_dir($file) as you see in my code above, but the results are still the same.

Dessa Simpson
  • 1,232
  • 1
  • 15
  • 30
Pinkie
  • 10,126
  • 22
  • 78
  • 124

6 Answers6

26

It should be like this, I think:

$files = scandir($dir); 
foreach($files as $file)
{
    if(is_file($dir.$file)){
      ....
Vasilis
  • 2,721
  • 7
  • 33
  • 54
rukya
  • 678
  • 4
  • 21
  • 1
    Since '.' and '..' are directories, "$file != '.' && $file != '..' &&" is redundant within the expression. And the trailing dir seperator makes no difference. – symcbean Oct 07 '11 at 12:29
8

Just use is_file.

Example:

foreach($files as $file)
{
    if( is_file($file) )
    {
       // Something
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Aurelio De Rosa
  • 21,856
  • 8
  • 48
  • 71
  • I could, but for my specific example i wanted to know why is_dir() was not working. Thanks +1 – Pinkie Oct 07 '11 at 09:03
2

This will scan the files then check if . or .. is in an array. Then push the files excluding . and .. in the new files[] array.

Try this:

$scannedFiles = scandir($fullPath);
$files = [];

foreach ($scannedFiles as $file) {
    if (!in_array(trim($file), ['.', '..'])) {
        $files[] = $file;
    }
}
1

What a pain for something so seemingly simple! Nothing worked for me... To get a result I assumed the file name had an extension which it must in my case.

if ($handle = opendir($opendir)) {
    while (false !== ($entry = readdir($handle))) {
        $pos = strpos( $entry, '.' );
        if ($entry != "." && $entry != ".." && is_numeric($pos)  ) {

............ good entry

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • well, you pointed that out, but still, there are everyday allday files without dots in their names. – dachi Feb 27 '14 at 17:22
1

Use the DIRECTORY_SEPARATOR constant to append the file to its directory path too.

    function getFileNames($directoryPath) {
        $fileNames = [];
        $contents = scandir($directoryPath);

        foreach($contents as $content) {
            if(is_file($directoryPath . DIRECTORY_SEPARATOR . $content)) {
                array_push($fileNames, $content);
            }
        }

        return $fileNames;
    }
rplaurindo
  • 1,277
  • 14
  • 23
1

This is a quick and simple one liner to list ONLY files. Since the user wants to list only files, there is no need to scan the directory and return all the contents and exclude the directories. Just get the files of any type or specific type. Use * to return all files regardless of extension or get files with a specific extension by replacing the * with the extension.

Get all files regardless of extension:

$files = glob($dir . DIRECTORY_SEPARATOR . "*");

Get all files with the php extension:

$files = glob($dir . DIRECTORY_SEPARATOR . "*.php");

Get all files with the js extension:

$files = glob($dir . DIRECTORY_SEPARATOR . "*.js");

I use the following for my sites:

function fileList(string $directory, string $extension="") :array
{
    $filetype = '*';
    if(!empty($extension) && mb_substr($extension, 0, 1, "UTF-8") != '.'):
        $filetype .= '.' . $extension;
    else:
        $filetype .= $extension;
    endif;
    return glob($directory . DIRECTORY_SEPARATOR . $filetype);
}

Usage :

$files = fileList($configData->includesDirectory, '');

With my custom function, I can include an extension or leave it empty. Additionally, I can forget to place the . before the extension and it will succeed.

JLDN Admin
  • 111
  • 9