Implementation code:
/**
* PHP non-recursive implementation query all files in this directory
* @param unknown $dir
* @return multitype:|multitype:string * *
function Scanfiles ($dir) {
if (! Is_dir ($dir)) return
array ();
Compatible with each operating system
$dir = RTrim (str_replace (' \ \ ', '/', $dir), '/'. '/';
Stack, the default value is the incoming directory
$dirs = array ($dir);
The container for all files is placed
$rt = Array ();
do {
//stack
$dir = Array_pop ($dirs);
Scan the directory
$tmp = Scandir ($dir);
foreach ($tmp as $f) {
//filter ...
if ($f = = '. ' | | $f = = ' ... ')
Continue;
Combines the current absolute path
$path = $dir. $f;
If it is a directory, press the stack.
if (Is_dir ($path)) {
Array_push ($dirs, $path. '/' );
} else if (Is_file ($path)) {//If it is a file, put in the container
$rt [] = $path;}} while
($dirs);//until there is no directory R in the stack
Eturn $rt;
}
With another article: Do not recursively traverse the directory of files
If you want to traverse all the files (including subdirectories) in a directory, the first thought is to use recursion: first process the current directory, and then process the subdirectories under the current directory. Can you do without recursion? Before the data structure of the time to see, recursion is actually the use of the stack to achieve, the characteristics of recursion is constantly called itself, the last call is the first execution, the penultimate call is the second execution, and so on, and so on, the initial call is final execution. If we understand the principle of recursion, we can actually convert all the implementations of recursion into a non recursive implementation.
To iterate through all the files in a directory in a non recursive way, the main idea is three steps:
1. Create an array that will be traversed by the directory (in fact, create a stack)
2. Loop over the array, the condition that the loop ends is that the array is empty;
3. Each loop, processing an element in the array, and delete the element, if this element is a directory, then add all the child elements of the directory to the array;
The code written in this way is as follows:
/**
* Traverses all files in a directory
* @param string $dir
/function Scanall ($dir)
{
$list = array ();
$list [] = $dir;
while (count ($list) > 0)
{
//pop-up array the last element
$file = Array_pop ($list);
Process the current file
echo $file. " \ r \ n ";
If it is a directory if
(Is_dir ($file))
{
$children = Scandir ($file);
foreach ($children as $child)
{
if ($child!== '. ' && $child!== ' ... ')
{
$list [] = $file. ' /'. $child;}}}}
Here I do not think recursion has a lot of shortcomings, in fact, in many cases, with the return design is very concise and readable, as to the efficiency of the problem, unless the depth of the recursion is particularly large, it will have an impact.
The following is a recursive implementation, in contrast:
/**
* traverses all files (recursive implementations) of a directory
* @param string $dir
/function ScanAll2 ($dir)
{
echo $dir. " \ r \ n ";
if (Is_dir ($dir))
{
$children = Scandir ($dir);
foreach ($children as $child)
{
if ($child!== '. ' && $child!== ' ... ')
{
scanAll2 ($dir. '/'. $child);}}}}
Run found that the results of two functions slightly different, mainly in the order of printing. The order of the results of a function is inverted, because the order of the stack is exactly the same as the order of the Scandir, you can change the 21st line:
$children = Array_reverse (Scandir ($file));
The result is exactly the same.