通用目錄遞歸遍歷,可限制深度,將符合條件的檔案路徑收集至 $files 陣列。
<?php
class FindFile {
public $files = [];
protected $maxdepth = 0;
public function process($spath, $maxdepth = 0) {
$this->maxdepth = (is_numeric($maxdepth) && $maxdepth > 0) ? $maxdepth : 0;
$this->files = [];
$this->traversing($spath);
}
private function traversing($spath, $depth = 1) {
if ($handle = opendir($spath)) {
while (($file = readdir($handle)) !== false) {
if ($file === '.' || $file === '..') continue;
$curfile = $spath . '/' . $file;
if (is_dir($curfile)) {
if ($this->maxdepth === 0 || $depth < $this->maxdepth)
$this->traversing($curfile, $depth + 1);
} else {
$this->handle($curfile);
}
}
closedir($handle);
}
}
protected function handle($file) {
$this->files[] = $file; // 子類覆寫此方法實現具體邏輯
}
}
繼承 FindFile,覆寫 handle() 檢測並清除檔案頭部 BOM (0xEF 0xBB 0xBF)。
<?php
class UnsetBom extends FindFile {
private $filetype = [];
public function __construct(array $filetype = []) { $this->filetype = $filetype; }
protected function handle($file) {
if ($this->check_ext($file) && $this->check_utf8bom($file)) {
$this->clear_utf8bom($file);
$this->files[] = $file; // 記錄已處理檔案
}
}
private function check_utf8bom($file) {
$content = file_get_contents($file);
return strlen($content) >= 3
&& ord($content[0]) === 0xEF
&& ord($content[1]) === 0xBB
&& ord($content[2]) === 0xBF;
}
private function clear_utf8bom($file) {
$content = file_get_contents($file);
file_put_contents($file, substr($content, 3));
}
private function check_ext($file) {
$ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
return empty($this->filetype) || in_array($ext, $this->filetype);
}
}
<?php
require 'FindFile.class.php';
require 'UnsetBom.class.php';
$folder = __DIR__;
$obj = new UnsetBom(['php', 'css', 'js', 'html']);
$obj->process($folder);
print_r($obj->files); // 輸出已清除 BOM 的檔案清單
FindFile::traversing() 定義遍歷骨架,handle() 留待子類實作具體處理邏輯。handle()。maxdepth 參數防止無限遞歸或效能問題。class CountLines extends FindFile {
public $totalLines = 0;
protected function handle($file) {
if (in_array(pathinfo($file, PATHINFO_EXTENSION), ['php','js','css','html'])) {
$this->totalLines += count(file($file));
}
}
}
$counter = new CountLines();
$counter->process('/var/www/project');
echo "總行數: {$counter->totalLines}";
FindFile 以模板方法模式封裝目錄遞歸遍歷,UnsetBom 展示如何輕鬆衍生具體功能。此架構讓檔案批次處理任務 (編碼轉換、關鍵字替換、靜態分析等) 變得結構化、可複用、易測試。