| 函數 | 說明 |
|---|---|
| opendir(path, context) | 開啟目錄控制代碼,成功回傳 resource,失敗回傳 false |
| readdir(handle) | 讀取目錄下一個項目(檔案/子目錄/./..),到達末尾回傳 false |
| closedir(handle) | 關閉目錄控制代碼,釋放資源 |
<?php
$dir = opendir("bkjia"); // 相對路徑
while (($file = readdir($dir)) !== false) {
echo "filename: " . $file . "<br />";
}
closedir($dir);
?>
輸出:
filename: . filename: .. filename: cat.gif filename: dog.gif filename: food filename: horse.gif
<?php
function getSubDirs($dir) {
$subdirs = [];
if (!$dh = opendir($dir)) return $subdirs;
while ($f = readdir($dh)) {
if ($f === '.' || $f === '..') continue; // 跳過特殊項目
$path = $dir . '/' . $f; // 完整路徑
if (is_dir($path)) {
$subdirs[] = $f; // 或存完整路徑 $path
}
}
closedir($dh);
return $subdirs;
}
$arr = getSubDirs("tmp");
print_r($arr);
/* 輸出範例:
Array (
[0] => Hello
[1] => NowaMagic
)
*/
?>
<?php
function tree($directory) {
$mydir = dir($directory);
echo "<ul>\n";
while ($file = $mydir->read()) {
$full = "$directory/$file";
if (is_dir($full) && $file !== '.' && $file !== '..') {
echo "<li><font color=\"#ff00cc\"><b>$file</b></font></li>\n";
tree($full); // 遞迴
} else {
echo "<li>$file</li>\n";
}
}
echo "</ul>\n";
$mydir->close();
}
echo "<h2>目錄為粉紅色</h2><br>\n";
tree("./bkjia");
?>
<?php
function listDir($dir) {
if (is_dir($dir)) {
if ($dh = opendir($dir)) {
while (($file = readdir($dh)) !== false) {
$full = $dir . "/" . $file;
if (is_dir($full) && $file !== '.' && $file !== '..') {
echo "<b><font color='red'>目錄:</font></b>$file<br><hr>";
listDir($full . "/");
} else {
if ($file !== '.' && $file !== '..') {
echo "$file<br>";
}
}
}
closedir($dh);
}
}
}
listDir("./bkjia");
?>
更物件導向、支援迭代器介面、自動過濾 . 與 ..:
<?php
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator('./bkjia', RecursiveDirectoryIterator::SKIP_DOTS)
);
foreach ($iterator as $file) {
$indent = str_repeat(' ', $iterator->getDepth());
echo $indent . ($file->isDir() ? '[D] ' : '[F] ') . $file->getFilename() . "\n";
}
?>
| 方法 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| opendir/readdir | 底層控制細緻、記憶體效率高 | 需手動過濾 . ..、程式碼較冗長 | 大量檔案、需精細控制、舊版 PHP |
| dir() 物件 | OO 風格、內建 read/close | 功能同 opendir | 偏好 OO 風格專案 |
| glob() | 支援萬用字元模式匹配 | 一次載入所有結果佔記憶體 | 模式匹配、中小目錄 |
| scandir() | 一次取得陣列、語法簡潔 | 大目錄記憶體壓力大 | 需陣列操作、中小目錄 |
| SPL Iterators | 標準化、支援過濾、遞迴、鏈式操作 | 物件開銷略高 | 現代專案首選 |
!== false,因檔名可能為 "0" 導致 while($file = readdir()) 提早結束DIRECTORY_SEPARATOR 或 /(Windows 也支援)opendir() 失敗時回傳 false,建議加 @ 抑制警告並自行處理is_dir() 會跟隨連結,遞迴時可能陷入循環,需用 is_link() 檢查掌握 opendir/readdir/closedir 基礎三部曲是理解 PHP 檔案系統操作的關鍵。現代專案建議直接使用 SPL RecursiveDirectoryIterator,程式碼更簡潔、健壯、符合 PSR 標準。若需模式匹配,glob() 是輕量好選擇。