102

For some reason, I keep getting a '1' for the file names with this code:

if (is_dir($log_directory))
{
    if ($handle = opendir($log_directory))
    {
        while($file = readdir($handle) !== FALSE)
        {
            $results_array[] = $file;
        }
        closedir($handle);
    }
}

When I echo each element in $results_array, I get a bunch of '1's, not the name of the file. How do I get the name of the files?

Facundo Casco
  • 10,065
  • 8
  • 42
  • 63
Dexter
  • 5,666
  • 6
  • 33
  • 45
  • 1
    There's a few options using [glob](http://us2.php.net/glob). – allnightgrocery May 27 '10 at 16:34
  • possible duplicate of [Get the hierarchy of a directory with PHP](http://stackoverflow.com/questions/660644/get-the-hierarchy-of-a-directory-with-php) – e-sushi Dec 16 '13 at 12:59
  • 1
    The problem the poster had was that assignment has a very low priority, so the '!==' operator gets evaluated first and the binary result of that operation then gets assigned to $file. The only fix needed is to use ($file = readdir($handle)) !== FALSE" – Omn Jan 03 '18 at 18:36
  • this works: https://halgatewood.com/free-php-list-files-in-a-directory-script – Gabriel Mar 16 '18 at 15:52
  • from 69 votes to 70. I feel like the opposite of Hank Moody – Bruno Francisco Apr 25 '19 at 18:02

16 Answers16

196

Don't bother with open/readdir and use glob instead:

foreach(glob($log_directory.'/*.*') as $file) {
    ...
}
kamal pal
  • 4,187
  • 5
  • 25
  • 40
Tatu Ulmanen
  • 123,288
  • 34
  • 187
  • 185
  • 27
    You might want to wrap an `array_filter(..., 'is_file')` around that glob since the question asks for files. – salathe May 27 '10 at 18:09
  • 28
    Not all filenames have the form `*.*`: just use `*` instead. – jameshfisher Feb 24 '14 at 17:17
  • How can we get all files within list of extensions? E.g. if we want all .php and .js files ? – Nis Apr 30 '14 at 04:33
  • 3
    Yeah, this answer isn't very robust. Files don't need to have extensions and directories can be named `something.something`. It's better to use `array_filter` and `glob($log_directory.'/*')`. – Andrew May 29 '14 at 16:33
  • I upvoted this becuase I just needed the simple answer and all the relevant files for my use case would be `*.*`. A more robust expression would make this an even better answer. – TecBrat May 24 '17 at 17:08
  • PHP 7.1 supports UTF-8 filenames on Windows ✌ – Andrei Krasutski Oct 11 '17 at 16:30
  • Actually answer with DirectoryIterator is much cleaner and offers much more extension opportunities in case you need more information. – Bartosz Kubicki Sep 28 '19 at 08:47
  • @Tatu Ulmanen, how does `glob` compare with `DirectoryIterator` as an alternative? In reading through other posts, it seems it more efficient when listing a large number of files compared to `glob`. – Motivated Jun 29 '23 at 10:14
  • @BartoszKubicki, when you say extension opportunities, do you mean the ability to extend the code? If yes, how is `glob` restrictive? – Motivated Jun 29 '23 at 10:14
60

SPL style:

foreach (new DirectoryIterator(__DIR__) as $file) {
  if ($file->isFile()) {
      print $file->getFilename() . "\n";
  }
}

Check DirectoryIterator and SplFileInfo classes for the list of available methods that you can use.

Ilija
  • 4,105
  • 4
  • 32
  • 46
  • Great way to get just files and just their names instead of the entire path, thanks! – Chris Nov 06 '15 at 17:22
  • 1
    Yes. For full paths, you can use `getPathname`: http://php.net/manual/en/splfileinfo.getpathname.php – Ilija Nov 08 '15 at 08:42
24

As the accepted answer has two important shortfalls, I'm posting the improved answer for those new comers who are looking for a correct answer:

foreach (array_filter(glob('/Path/To/*'), 'is_file') as $file)
{
    // Do something with $file
}
  1. Filtering the globe function results with is_file is necessary, because it might return some directories as well.
  2. Not all files have a . in their names, so */* pattern sucks in general.
Aliweb
  • 1,891
  • 3
  • 21
  • 44
  • This is a clean execution that worked for me. Previous answers showed directories in results which I did not want. – AWP Jan 07 '19 at 16:42
  • You sir need more upvotes! Actually (on windows) I had to use `basename($file)` to get only the file name instead of the whole path with filename. – Pauloco May 31 '20 at 03:19
  • The OP didn't mention he wasn't interested in "directories", besides, directories are files as well. If you also want files in sub folders, you have to use ```is_dir``` and just create a function that calls itself. – user281681 Dec 07 '22 at 00:41
18

You need to surround $file = readdir($handle) with parentheses.

Here you go:

$log_directory = 'your_dir_name_here';

$results_array = array();

if (is_dir($log_directory))
{
        if ($handle = opendir($log_directory))
        {
                //Notice the parentheses I added:
                while(($file = readdir($handle)) !== FALSE)
                {
                        $results_array[] = $file;
                }
                closedir($handle);
        }
}

//Output findings
foreach($results_array as $value)
{
    echo $value . '<br />';
}
Mike Moore
  • 7,228
  • 10
  • 42
  • 63
16

Just use glob('*'). Here's Documentation

Fletcher Moore
  • 13,558
  • 11
  • 40
  • 58
14

I have smaller code todo this:

$path = "Pending2Post/";
$files = scandir($path);
foreach ($files as &$value) {
    echo "<a href='http://localhost/".$value."' target='_blank' >".$value."</a><br/><br/>";
}
Woody
  • 1,449
  • 3
  • 19
  • 27
YooRich.com
  • 141
  • 1
  • 3
9

On some OS you get . .. and .DS_Store, Well we can't use them so let's us hide them.

First start get all information about the files, using scandir()

// Folder where you want to get all files names from
$dir = "uploads/";

/* Hide this */
$hideName = array('.','..','.DS_Store');    

// Sort in ascending order - this is default
$files = scandir($dir);
/* While this to there no more files are */
foreach($files as $filename) {
    if(!in_array($filename, $hideName)){
       /* echo the name of the files */
       echo "$filename<br>";
    }
}
Dika
  • 2,213
  • 4
  • 33
  • 49
TheCrazyProfessor
  • 919
  • 1
  • 15
  • 31
4

It's due to operator precidence. Try changing it to:

while(($file = readdir($handle)) !== FALSE)
{
    $results_array[] = $file;
}
closedir($handle);
ircmaxell
  • 163,128
  • 34
  • 264
  • 314
2

glob() and FilesystemIterator examples:

/* 
 * glob() examples
 */

// get the array of full paths
$result = glob( 'path/*' );

// get the array of file names
$result = array_map( function( $item ) {
    return basename( $item );
}, glob( 'path/*' ) );


/* 
 * FilesystemIterator examples
 */

// get the array of file names by using FilesystemIterator and array_map()
$result = array_map( function( $item ) {
    // $item: SplFileInfo object
    return $item->getFilename();
}, iterator_to_array( new FilesystemIterator( 'path' ), false ) );

// get the array of file names by using FilesystemIterator and iterator_apply() filter
$it = new FilesystemIterator( 'path' );
iterator_apply( 
    $it, 
    function( $item, &$result ) {
        // $item: FilesystemIterator object that points to current element
        $result[] = (string) $item;
        // The function must return TRUE in order to continue iterating
        return true;
    }, 
    array( $it, &$result )
);
Danijel
  • 12,408
  • 5
  • 38
  • 54
1

You could just try the scandir(Path) function. it is fast and easy to implement

Syntax:

$files = scandir("somePath");

This Function returns a list of file into an Array.

to view the result, you can try

var_dump($files);

Or

foreach($files as $file)
{ 
echo $file."< br>";
} 
David Arenburg
  • 91,361
  • 17
  • 137
  • 196
Ad Kahn
  • 551
  • 4
  • 6
1

Another way to list directories and files would be using the RecursiveTreeIterator answered here: https://stackoverflow.com/a/37548504/2032235.

A thorough explanation of RecursiveIteratorIterator and iterators in PHP can be found here: https://stackoverflow.com/a/12236744/2032235

Community
  • 1
  • 1
jim_kastrin
  • 4,830
  • 2
  • 26
  • 28
0

I just use this code:

<?php
    $directory = "Images";
    echo "<div id='images'><p>$directory ...<p>";
    $Files = glob("Images/S*.jpg");
    foreach ($Files as $file) {
        echo "$file<br>";
    }
    echo "</div>";
?>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
merrais
  • 371
  • 2
  • 9
0

Use:

if ($handle = opendir("C:\wamp\www\yoursite/download/")) {

    while (false !== ($entry = readdir($handle))) {
        if ($entry != "." && $entry != "..") {
            echo "<b>" . preg_replace('/\\.[^.\\s]{3,4}$/', '', $entry) . "</b>";
        }
    }
    closedir($handle);
}

Source: http://chandreshrana.blogspot.com/2016/08/how-to-fetch-all-files-name-from-folder.html

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Chandresh
  • 361
  • 2
  • 7
0

Recursive code to explore all the file contained in a directory ('$path' contains the path of the directory):

function explore_directory($path)
{
    $scans = scandir($path);

    foreach($scans as $scan)
    {
        $new_path = $path.$scan;

        if(is_dir($new_path))
        {
            $new_path = $new_path."/";
            explore_directory($new_path);
        }
        else // A file
        {
            /*
                  Body of code
            */
        }
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Prashant Goel
  • 471
  • 4
  • 7
0

Little something I created for this:

function getFiles($path) {
    if (is_dir($path)) {
        $res = array();
        foreach (array_filter(glob($path ."*"), 'is_file') as $file) {
            array_push($res, str_replace($path, "", $file));                
        }
        return $res;
    }
    return false;
}
Kaloy
  • 91
  • 1
  • 12
0

This will list the files and create links that open in a new window. Just like a regular server index page:

<!DOCTYPE html>
<html>
<head>
    <title>Index of Files</title>
</head>
<body>
    <h1>Index of Files</h1>
    <ul>
        <?php
        // Get the current directory
        $dir = '.';
        
        // Open a directory handle
        if ($handle = opendir($dir)) {
            // Loop through each file in the directory
            while (false !== ($file = readdir($handle))) {
                // Exclude directories and the current/parent directory entries
                if ($file != "." && $file != ".." && !is_dir($file)) {
                    // Generate the link to the file
                    $link = $dir . '/' . $file;
                    
                    // Output the link
                    echo '<li><a href="' . $link . '" target="_blank">' . $file . '</a></li>';
                }
            }
            
            // Close the directory handle
            closedir($handle);
        }
        ?>
    </ul>
</body>
</html>
TV-C-1-5
  • 680
  • 2
  • 13
  • 19