dir() 函數回傳 Directory 類別實例,提供物件導向方式讀取目錄。雖然功能較 DirectoryIterator 簡單,但理解它有助於維護舊代碼與掌握 PHP 目錄操作演進歷程。
<?php
class Directory {
public string $path; // 目錄路徑
public resource $handle; // 目錄控制代碼
public function read(): string|false; // 讀取下一項
public function rewind(): void; // 重置指標到開頭
public function close(): void; // 關閉目錄
}
?>
<?php
$d = dir('/etc/php5');
echo "Handle: {$d->handle}\n";
echo "Path: {$d->path}\n";
while (false !== ($entry = $d->read())) {
echo $entry . "\n";
}
$d->close();
?>
<?php
// ❌ 錯誤:若檔名為 "0" 或空字串,迴圈會提前結束
while ($entry = $d->read()) { ... }
// ✅ 正確:嚴格比較 false
while (false !== ($entry = $d->read())) { ... }
// ✅ 也可用 foreach(PHP 內部處理了 false 檢查)
foreach ($d as $entry) {
echo $entry . "\n";
}
$d->close(); // foreach 不會自動關閉,需手動
?>
<?php
$d = dir('/var/www/html');
echo "目錄:{$d->path}\n";
echo "項目列表:\n";
while (false !== ($entry = $d->read())) {
if ($entry === '.' || $entry === '..') continue;
$fullPath = $d->path . DIRECTORY_SEPARATOR . $entry;
$info = [];
if (is_dir($fullPath)) {
$info[] = '[DIR]';
} else {
$info[] = '[FILE]';
$info[] = filesize($fullPath) . ' bytes';
}
$info[] = '權限: ' . substr(sprintf('%o', fileperms($fullPath)), -4);
$info[] = '修改: ' . date('Y-m-d H:i:s', filemtime($fullPath));
echo " $entry - " . implode(' | ', $info) . "\n";
}
$d->close();
?>
<?php
$d = dir('/tmp');
echo "第一次讀取:\n";
while (false !== ($e = $d->read())) echo " $e\n";
$d->rewind(); // 重置到開頭
echo "\n第二次讀取(rewind 後):\n";
while (false !== ($e = $d->read())) echo " $e\n";
$d->close();
?>
| 特性 | Directory | DirectoryIterator | scandir() |
|---|---|---|---|
| 風格 | 物件導向(舊式) | 物件導向(現代、SPL) | 程序式 |
| 可迭代 | 是 | 是(實作 Iterator) | 回傳陣列 |
| 檔案資訊 | 需自行 stat() | 內建 SplFileInfo | 需自行 stat() |
| 自動跳過 . 和 .. | 否 | 是(isDot()) | 否 |
| 遞迴支援 | 否 | RecursiveDirectoryIterator | 否 |
| 記憶體效率 | 逐行讀取 | 逐行讀取 | 載入整個陣列 |
<?php
// Directory 寫法
$d = dir($path);
while (false !== ($e = $d->read())) { ... }
$d->close();
// DirectoryIterator 寫法(推薦)
$iterator = new DirectoryIterator($path);
foreach ($iterator as $fileInfo) {
if ($fileInfo->isDot()) continue;
// $fileInfo 直接提供 isDir(), getSize(), getMTime(), getPerms() 等
}
?>
Directory 類別是 PHP 早期物件導向目錄操作的產物。現代代碼建議使用 DirectoryIterator / RecursiveDirectoryIterator(SPL 標準庫),功能更豐富、介面更一致、自動處理常見陷阱。理解 Directory 有助於閱讀舊專案代碼與理解 PHP 發展歷程。