所以是的:今天我正在懶惰和谷歌搜索曲奇解決方案的遞歸目錄列表,並遇到了這個。最後,我寫了自己的功能(至於爲什麼我花時間去Google這方面卻超出了我的想象 - 我似乎總覺得有必要重新發明輪子,因爲沒有合適的理由),我覺得我傾向於分享我的看法在這。
雖然有意見反對使用RecursiveDirectoryIterator,但我只是簡單地發表一個簡單的遞歸目錄函數,並避免在RecursiveDirectoryIterator中聲明的策略。
這就是:
function recursiveDirectoryList($root)
{
/*
* this next conditional isn't required for the code to function, but I
* did not want double directory separators in the resulting array values
* if a trailing directory separator was provided in the root path;
* this seemed an efficient manner to remedy said problem easily...
*/
if(substr($root, -1) === DIRECTORY_SEPARATOR)
{
$root = substr($root, 0, strlen($root) - 1);
}
if(! is_dir($root)) return array();
$files = array();
$dir_handle = opendir($root);
while(($entry = readdir($dir_handle)) !== false)
{
if($entry === '.' || $entry === '..') continue;
if(is_dir($root . DIRECTORY_SEPARATOR . $entry))
{
$sub_files = recursiveDirectoryList(
$root .
DIRECTORY_SEPARATOR .
$entry .
DIRECTORY_SEPARATOR
);
$files = array_merge($files, $sub_files);
}
else
{
$files[] = $root . DIRECTORY_SEPARATOR . $entry;
}
}
return (array) $files;
}
使用此功能,答案以獲得文件計數很簡單:
$dirpath = '/your/directory/path/goes/here/';
$files = recursiveDirectoryList($dirpath);
$number_of_files = sizeof($files);
但是,如果你不想數組的開銷的相應文件路徑 - 或者根本就不需要它 - 不需要按照推薦的方式將遞歸計數傳遞給遞歸函數。
人們可以簡單的修改我的原始功能進行計數這樣:
function recursiveDirectoryListC($root)
{
$count = 0;
if(! is_dir($root)) return (int) $count;
$dir_handle = opendir($root);
while(($entry = readdir($dir_handle)) !== false)
{
if($entry === '.' || $entry === '..') continue;
if(is_dir($root . DIRECTORY_SEPARATOR . $entry))
{
$count += recursiveDirectoryListC(
$root .
DIRECTORY_SEPARATOR .
$entry .
DIRECTORY_SEPARATOR
);
}
else
{
$count++;
}
}
return (int) $count;
}
在這兩個功能的執行opendir()函數應該被包裹在有條件的情況下,該目錄是不可讀或發生其他錯誤。請務必使正確的事:
if(($dir_handle = opendir($dir)) !== false)
{
/* perform directory read logic */
}
else
{
/* do something on failure */
}
希望這可以幫助別人......
來源
2013-01-18 15:33:09
rmf
只是一個句話:一個迭代器做什麼它的名字所暗示的。它遍歷一個可迭代的源代碼。這與迭代數組沒有區別。如果你想要結果排序,那麼你必須在foreach循環中執行此操作,或者編寫/使用函數來爲您執行此操作。 – Gordon 2010-03-27 11:03:32
@戈登真。但是,能夠將結果排序和/或直接過濾是我期望從遞歸目錄迭代器中獲得的一個特性 - 但我知道這可能不在SPL的spririt中,但仍然是這樣。實際上,還需要提出幾十行代碼(網上有數百個代碼片段,質量各不相同),以執行相當標準的任務,其中其他語言提供現成的功能。有時候讓我有點生氣。 – 2010-03-27 11:08:00
@Pekka因爲現在一切都可以是一個Iterable,所以不可能想出一個通用的排序方式。它應該如何知道我希望我的Person對象按$ firstName排序,但是我的Files by MTime?你有*腳本。如果您想通過泛型表達式查詢對象,請查看PHPLinq。 – Gordon 2010-03-27 11:14:21