1. 程式人生 > >php遍歷檔案的5種方式

php遍歷檔案的5種方式

在網上搜索了一下遍歷資料夾的函式,資料很多,但都不算特別的全。所以,今天粗略的總結一下,使用php 幾種常見的遍歷檔案的方式。

備註:大部分demo使用遞迴的方式進行條用

測試目錄如下圖:
這裡寫圖片描述

一:使用scandir 函式
1.1 函式封裝
scandir : 是php 自帶函式,返回當前目錄下的所有檔案和資料夾。注意:會有 ‘.’ 和’..’,分別代編當前目錄和上層目錄。

/**
 * 使用scandir 遍歷目錄
 *
 * @param $path
 * @return array
 */
function getDir($path)
{
    //判斷目錄是否為空
if(!file_exists($path)) { return []; } $files = scandir($path); $fileItem = []; foreach($files as $v) { $newPath = $path .DIRECTORY_SEPARATOR . $v; if(is_dir($newPath) && $v != '.' && $v != '..') { $fileItem = array_merge($fileItem
, getDir($newPath)); }else if(is_file($newPath)){ $fileItem[] = $newPath; } } return $fileItem; }

1.2程式呼叫:

echo('遍歷目錄開始');
$path = realpath('./m1/');
var_dump(getDir($path));
echo('遍歷目錄結束');

1.3 顯示結果

/usr/local/opt/[email protected]/bin/php
遍歷目錄開始array(9) {
[0]=>
string(48) “/Users/niedewang/PhpstormProjects/test/m1/1.html”
[1]=>
string(48) “/Users/niedewang/PhpstormProjects/test/m1/2.html”
[2]=>
string(50) “/Users/niedewang/PhpstormProjects/test/m1/demo.txt”
[3]=>
string(54) “/Users/niedewang/PhpstormProjects/test/m1/m2/m2_1.html”
[4]=>
string(54) “/Users/niedewang/PhpstormProjects/test/m1/m2/m2_2.html”
[5]=>
string(54) “/Users/niedewang/PhpstormProjects/test/m1/m2/m2_3.html”
[6]=>
string(57) “/Users/niedewang/PhpstormProjects/test/m1/m2/m3/m3_1.html”
[7]=>
string(56) “/Users/niedewang/PhpstormProjects/test/m1/m2/m3/m3_2.php”
[8]=>
string(56) “/Users/niedewang/PhpstormProjects/test/m1/m2/m3/m3_3.txt”
}
遍歷目錄結束
Process finished with exit code 0

1.4 注意事項

  • 難度係數:簡單
  • 注意事項: 注意迴圈的時候,過濾 ‘.’ 和 ‘..’ ,否則可能會導致死迴圈

二:使用glob函式

2.1 函式封裝
glob:是php 子系統自帶函式,功能和scandir 類似,但比它更加強大靈活。
比如 :glob(‘*.txt’),將會列舉出目錄下的所有為站名為.txt 的檔案。

/**
 * 使用glob 遍歷
 * @param $path
 */
function getDir2($path)
{

    //判斷目錄是否為空
    if(!file_exists($path)) {
        return [];
    }

    $fileItem = [];

    //切換如當前目錄
    chdir($path);

    foreach(glob('*') as $v) {
        $newPath = $path . DIRECTORY_SEPARATOR . $v;
        if(is_dir($newPath)) {
            $fileItem = array_merge($fileItem,getDir2($newPath));
        }else if(is_file($newPath)) {

            $fileItem[] = $newPath;
        }
    }

    return $fileItem;
}

2.2 函式呼叫方式

echo('遍歷目錄開始');
$path = realpath('./m1/');
var_dump(getDir2($path));
echo('遍歷目錄結束');

2.3 :顯示結果,同1.3 一致,不再展示
2.4 注意事項

  • 難易程度:非常容易,不需要過濾 . 和 ..
  • 靈活程度:非常靈活

三:使用opendir 函式
3.1 函式封裝
opendir : 返回一個目錄控制代碼,可以使用readdir 讀取這個目錄,也可以通過closedir 關閉這個目錄

/**
 * 使用opendir 函式遞迴
 */

function getDir3($path)
{
    if(!file_exists($path)) {
        return [];
    }
    $handle = opendir($path);
    $fileItem = [];
    if($handle) {
        while(($file = readdir($handle)) !== false) {
            $newPath = $path . DIRECTORY_SEPARATOR . $file;
            if(is_dir($newPath) && $file != '.' && $file != '..') {

                $fileItem = array_merge($fileItem,getDir3($newPath));
            }else if(is_file($newPath)) {
                $fileItem[] = $newPath;
            }
        }
    }
    @closedir($handle);

    return$fileItem;
}

3.2 呼叫方式

echo('遍歷目錄開始');
$path = realpath('./m1/');
var_dump(getDir5($path));
echo('遍歷目錄結束');

3.3 注意事項
需要過濾 ‘.’ 和 ”

四:使用dir 函式
4.1 和opendir 函式非常類似,它更加的面向物件。

/**
 * dir 函式的方式,物件
 *
 * @param $path
 * @return array
 */
function getDir4($path) {

    if(!file_exists($path)) {
        return [];
    }
    $handel = dir($path);
    $fileItem = [];
    if($handel) {
        while(($file = $handel->read()) !== false) {
            $newPath = $path . DIRECTORY_SEPARATOR . $file;
            if(is_dir($newPath) && $file != '.' && $file != '..') {

                $fileItem = array_merge($fileItem,getDir4($newPath));
            }else if(is_file($newPath)) {
                $fileItem[] = $newPath;
            }
        }
    }
    $handel->close();

    return $fileItem;
}

4.4 注意事項
需要過濾 ‘.’ 和 ”

五:使用spl 庫

使用spl 庫中的物件,好處是不需要進行迭代,書寫起來非常容易

/**
 * 使用 spl 庫
 *
 * @param $path
 */
function getDir5($path)
{
    $dir = new RecursiveDirectoryIterator($path);
    $fileItem = [];
    foreach(new RecursiveIteratorIterator($dir) as $k=>$v) {

        $fileName = $v->getBaseName();
        if($fileName != '.' && $fileName != '..') {
            $fileItem[] = $k;
        }
    }

    return $fileItem;
}

5.2 呼叫方式:

echo('遍歷目錄開始');
$path = realpath('./m1/');
var_dump(getDir4($path));
echo('遍歷目錄結束');

5.3 注意事項:

難以程度:容易。
- 類名有點長,但非常容易使用,畢竟不需要自己寫迭代函數了。
- 不需要處理 . 和 .. 兩個特殊目錄

六:總結

  • 如果目錄數量不是很多,建議使用 scandir 方式,應為函式名容易記憶。
  • 如果要求靈活性,比如只顯示某一型別的檔案等,使用glob 方式,
    本身就有類似搜尋的功能。
  • 如果目錄下檔案較多,建議使用opendir 和dir 的方式。
  • 因為scandir 和glob都是返回滿足條件的所有檔案,如果有幾十萬這樣,返回素組非常龐大。
    opendir迴圈可控性要強一些,比如可以返回前100個檔案等。這個還需要論證
  • 如果希望程式碼簡介,使用spl 庫的方式。程式碼量少