note 96326 added to function.scandir
| From: | boen dot robot at gmail dot com | Date: | Sat, 20 Feb 2010 18:10:54 +0000 |
| Subject: | note 96326 added to function.scandir | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-166213@lists.php.net to get a copy of this message | ||
If you have a folder with many files and/or subfolders, doing a recursive scandir will likely either
slow down your application, or cause a high rise in RAM consumption due to the large size of the
generated array.
To help with this, as well as to make processing of files in a folder easier, I wrote a function
that reads a folder and its subfolders recursively, and calls a function upon each match.
<?php
/**
* Calls a function for every file in a folder.
*
* @author Vasil Rangelov a.k.a. boen_robot
*
* @param string $callback The function to call. It must accept one argument that is a relative
filepath of the file.
* @param string $dir The directory to traverse.
* @param array $types The file types to call the function for. Leave as NULL to match all types.
* @param bool $recursive Whether to list subfolders as well.
* @param string $baseDir String to append at the beginning of every filepath that the callback will
receive.
*/
function dir_walk($callback, $dir, $types = null, $recursive = false, $baseDir = '') {
if ($dh = opendir($dir)) {
while (($file = readdir($dh)) !== false) {
if ($file === '.' || $file === '..') {
continue;
}
if (is_file($dir . $file)) {
if (is_array($types)) {
if (!in_array(strtolower(pathinfo($dir . $file, PATHINFO_EXTENSION)), $types,
true)) {
continue;
}
}
$callback($baseDir . $file);
}elseif($recursive && is_dir($dir . $file)) {
dir_walk($callback, $dir . $file . DIRECTORY_SEPARATOR, $types, $recursive, $baseDir
. $file . DIRECTORY_SEPARATOR);
}
}
closedir($dh);
}
}
?>
Of course, because it is recursive, a folder with many levels of folders could potentially consume
lots of memory, but then again, so can every other recursive scandir implementation here.
BTW, there's also the RecursiveDirectoryIterator SPL class:
http://bg.php.net/manual/en/class.recursivedirectoryiterator.php
which, even if using the same approach, will most likely be faster and hold down deeper levels
(because it works on the C level), but this one will always work, regardless of settings... even on
PHP4.
Point is, avoid recursive scandir implementations.
----
Server IP: 217.75.128.29
Probable Submitter: 83.148.87.92
----
Manual Page -- http://www.php.net/manual/en/function.scandir.php
Edit -- https://master.php.net/note/edit/96326
Del: integrated -- https://master.php.net/note/delete/96326/integrated
Del: useless -- https://master.php.net/note/delete/96326/useless
Del: bad code -- https://master.php.net/note/delete/96326/bad+code
Del: spam -- https://master.php.net/note/delete/96326/spam
Del: non-english -- https://master.php.net/note/delete/96326/non-english
Del: in docs -- https://master.php.net/note/delete/96326/in+docs
Del: other reasons-- https://master.php.net/note/delete/96326
Reject -- https://master.php.net/note/reject/96326
Search -- https://master.php.net/manage/user-notes.php