<?php
// 簡單地使用 FilesystemIterator
// 就可以略過點和雙點
// 並以陣列方式使用
// new FilesystemIterator( 路徑 , 選項 ) : 陣列
$array_file_list = new FilesystemIterator( PATH_ROOT . 'folder/', FilesystemIterator::SKIP_DOTS );
?>
(PHP 4, PHP 5, PHP 7, PHP 8)
dir — 傳回 Directory 類別的實例
版本 | 說明 |
---|---|
8.0.0 |
context 現在可以為 null。 |
範例 #1 dir() 範例
請注意以下範例中檢查 Directory::read() 返回值的方式。我們明確地測試返回值是否與 false
完全相同(值和類型都相同 - 有關更多資訊,請參閱比較運算子),因為否則,任何名稱評估為 false
的目錄項目都會停止迴圈。
<?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();
?>
上述範例的輸出結果類似如下:
Handle: Resource id #2 Path: /etc/php5 . .. apache cgi cli
注意:
read 方法返回目錄項目的順序取決於系統。
<?php
// 簡單地使用 FilesystemIterator
// 就可以略過點和雙點
// 並以陣列方式使用
// new FilesystemIterator( 路徑 , 選項 ) : 陣列
$array_file_list = new FilesystemIterator( PATH_ROOT . 'folder/', FilesystemIterator::SKIP_DOTS );
?>
這個蠻不錯的。在試圖從我的大量音樂收藏中找出 .jpg 檔案卻感到沮喪之後(PHP 會耗盡記憶體),我想應該要有一個 preg_ls 函式。
function preg_ls ($path=".", $rec=false, $pat="/.*/") {
// 它會被重複使用,確保我們編譯它以提高速度。
$pat=preg_replace("|(/.*/[^S]*)|s", "\\1S", $pat);
//從路徑中移除尾部的斜線
while (substr($path,-1,1)=="/") $path=substr($path,0,-1);
// 同時,確保 $path 是一個目錄,並修復任何錯誤
if (!is_dir($path)) $path=dirname($path);
// 斷言 $rec 的真假值,不允許純量值表示真
if ($rec!==true) $rec=false;
// 取得目錄控制代碼
$d=dir($path);
// 初始化輸出陣列
$ret=Array();
// 迴圈讀取,直到讀取完畢
while (false!==($e=$d->read())) {
// 忽略父目錄和自身連結
if (($e==".")||($e=="..")) continue;
// 如果以遞迴方式運作且為目錄,則抓取並合併
if ($rec && is_dir($path."/".$e)) {
$ret=array_merge($ret,preg_ls($path."/".$e,$rec,$pat));
continue;
}
// 如果不符合,則排除
if (!preg_match($pat,$e)) continue;
// 在所有其他情況下,將其添加到輸出陣列
$ret[]=$path."/".$e;
}
// 最後,返回陣列
return $ret;
}
區區 18 行程式碼,表現不錯吧,您覺得呢?
範例用法
foreach (preg_ls("/etc/X11", true, "/.*\.conf/i") as $file) echo $file."\n";
輸出
/etc/X11/xkb/README.config
/etc/X11/xorg.conf-vesa
/etc/X11/xorg.conf~
/etc/X11/gui.conf
/etc/X11/xorg.conf
/etc/X11/xorg.conf-fbdev
請注意,在 Windows 系統上使用 PHP 5.x 版本且非 Unicode 程式的情況下,dir 物件將使用預設編碼。
因此,如果您有名稱包含目前預設編碼不支援的字元之檔案,則 dir->read() 方法將返回錯誤的項目。
<?php
/*
** 此指令碼與一個檔案位於相同的目錄中,該檔案的名稱包含
** 目前預設編碼不支援的字元。
*/
$d = dir("./");
while(false !== ($e = $d->read()))
echo $e . '<br/>';
?>
這將針對每個不支援的字元列印「?」,而不是正確的檔案名稱。 因此,如果您在列舉後立即使用 is_file/is_dir 進行檢查,請務必小心。
關於 samuel 提到的 dir() 函式無法正確支援 Unicode 的問題,這完全取決於編碼。 該函式並不會在內部將 Unicode 字元更改為問號 (?),就像我一開始以為的那樣。 如果您只是嘗試以 UTF-8 輸出它們,它們就會正確顯示。
<?php
/*
新的 PHP8 遞迴函式
使用 FilesystemIterator 產生陣列路徑
*/
$recurcive_path = [];
rdir(path, $recurcive_path);
var_dump($recurcive_path);
function rdir(string $path, array &$recurcive_path): string
{
if ($path != '') {
$recurcive_path[] = $path;
$array_list = iterator_to_array(new FilesystemIterator($path, FilesystemIterator::SKIP_DOTS));
foreach ($array_list as $name) {
$pathname = $name->getPathname();
if (is_dir($pathname) && $name->getFilename()[0] != '.') {
$path = rdir($pathname, $recurcive_path);
}
}
return $path;
}
return '';
}
?>
取得 http://www.example.com/directory 的目錄
<?php
function remotedir($dir)
{
$dir = str_replace(" ", "%20", html_entity_decode($dir));
if (($rh = fopen($dir, 'rb')) === FALSE) { return false; }
$i = 0;
while (!feof($rh)) {
$archivos = fgetss($rh);
$directorio[$i++] = trim( substr($archivos,1,strpos($archivos," ",1)) );
}
fclose($rh);
return $directorio;
}
?>