[英]PHP RecursiveDirectoryIterator return but do not traverse directory matching “x”
我正在用PHP編寫磁盤目錄應用程序。 我的腳本循環遍歷目錄,將所有文件名和元數據存儲在數據庫中。 有些目錄我不想走下去。 我希望迭代器只是簡單地返回這些目錄的名稱,就像它們是文件一樣,然后移動到下一個兄弟。 我已經實現了一個RecursiveCallbackFilterIterator,它允許根據匹配的文件名模式省略目錄:
$filter = array(".app");
$files = new RecursiveIteratorIterator(
new RecursiveCallbackFilterIterator(
new RecursiveDirectoryIterator(
$zpath,
RecursiveDirectoryIterator::SKIP_DOTS
),
function ($current, $key, $iterator) use ($filter) {
$match = 0;
foreach ($filter as $skip) {
if (substr($current->getBaseName(), -4, 4) == $skip) {
$match = 1;
}
}
if ($match) {
return false;
} else {
return true;
}
}
),
RecursiveIteratorIterator::SELF_FIRST,
RecursiveIteratorIterator::CATCH_GET_CHILD
);
foreach ($files as $splFileInfo) {
$path = $splFileInfo->getRealPath();
echo $path."\n";
}
我的問題是,如何修改此代碼,以便匹配模式的目錄包含在結果集中,但不會返回到迭代器進行進一步遍歷?
到目前為止,我發現RecursiveCallbackFilterIterator的所有示例都顯示了上面的一些變化(例如,省略某些文件或目錄)。 我只想返回目錄名稱,如果它匹配模式,然后繼續下一個兄弟。
換句話說,我需要改變這個:
File1.txt
File2.txt
Folder1/
Folder1/FileA.txt
Folder1/FileB.txt
MyThing.app/
MyThing.app/Contents/
Mything.app/Contents/Manifest.plist
Mything.app/Menu.nib
Portfolio.zip
Zee.txt
進入:
File1.txt
File2.txt
Folder1/
Folder1/FileA.txt
Folder1/FileB.txt
MyThing.app
Portfolio.zip
Zee.txt
我已經創建了一個eval.in來測試它,雖然在這個環境中我無法創建目錄,所以我只測試文件,但是也應該和dir一樣。
file_put_contents("./file2.txt", "test");
file_put_contents("./Zee.txt", "test");
file_put_contents("./fileA.txt", "test");
file_put_contents("./fileB.txt", "test");
file_put_contents("./manifest.plist", "test");
file_put_contents("./manifest.app", "test");
file_put_contents("./MyApp.app", "test");
file_put_contents("./Menu.nib", "test");
$zpath=realpath("./");
$filter = array(".app");
$appFolders =array();
$files = new RecursiveIteratorIterator(
new RecursiveCallbackFilterIterator(
new RecursiveDirectoryIterator(
$zpath,
RecursiveDirectoryIterator::SKIP_DOTS
),
function ($current, $key, $iterator) use ($filter) {
foreach ($filter as $skip) {
preg_match_all("(".$skip.")", $current->getRealPath(), $result);
if (!empty($result[0])) {
$GLOBALS["appFolders"][] =$current->getRealPath();
return false;
}
}
return true;
}
),
RecursiveIteratorIterator::SELF_FIRST,
RecursiveIteratorIterator::CATCH_GET_CHILD
);
echo "\nFiles:\n";
foreach ($files as $splFileInfo) {
$path = $splFileInfo->getRealPath();
echo $path."\n";
}
echo "\nAppFolders:\n";
foreach ($appFolders as $app){
echo $app."\n";
}
輸出是:
Files:
/tmp/execpad-4917ea112c86/file2.txt
/tmp/execpad-4917ea112c86/input-4917ea112c86
/tmp/execpad-4917ea112c86/manifest.plist
/tmp/execpad-4917ea112c86/Menu.nib
/tmp/execpad-4917ea112c86/output-4917ea112c86
/tmp/execpad-4917ea112c86/fileA.txt
/tmp/execpad-4917ea112c86/fileB.txt
/tmp/execpad-4917ea112c86/Zee.txt
/tmp/execpad-4917ea112c86/source-4917ea112c86
AppFolders:
/tmp/execpad-4917ea112c86/MyApp.app
/tmp/execpad-4917ea112c86/manifest.app
感謝Edwin的回答,我能夠創建完美的代碼。 我想我會在這里分享它,以防它對其他人有幫助。 關鍵是我需要更多地了解splFileInfo可用的方法,特別是Path。 通過檢查Path,可以知道父文件,而不是文件名,是否包含通配符。 將此與fnmatch相結合,我們可以推測,如果文件位於“.app”目錄的下游,則完全跳過該分支,同時仍包括父級。 謝謝埃德溫!
// Do not descend into matching directories
$wopt_nodescend = array("*.app", "*.sparsebundle");
// Ignore matching files and directories
$wopt_ignore = array(".DS_Store", "*.jdk");
$nodescended = 0;
$ignored = 0;
$files = new RecursiveIteratorIterator(
new RecursiveCallbackFilterIterator(
new RecursiveDirectoryIterator(
$zpath,
RecursiveDirectoryIterator::SKIP_DOTS
),
function ($current, $key, $iterator) use ($wopt_ignore, $wopt_nodescend) {
global $nodescended, $ignored;
$clean = true;
if (is_array($wopt_ignore)) {
foreach ($wopt_ignore as $wildcard) {
if (fnmatch($wildcard, $current->getFilename())) {
$clean = false;
$ignored++;
echo "Skipping: ".$current->getFilename()."\n";
}
}
}
if (is_array($wopt_nodescend)) {
foreach ($wopt_nodescend as $wildcard) {
if (fnmatch($wildcard, $current->getPath())) {
$clean = false;
$nodescended++;
echo "Nodescending: ".$current->getFilename()."\n";
}
}
}
return $clean;
}
),
RecursiveIteratorIterator::SELF_FIRST,
RecursiveIteratorIterator::CATCH_GET_CHILD
);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.