<?php class Dir { /** * 掃描目錄下全部文件, * @var array */ protected static $files = []; public static $ret = []; /** * 掃描目錄路徑 * @param $path string 帶掃描的路徑 * @param array $options 要附加的選項,後面能夠根據本身需求擴展 * @return array * @author: Vencenty */ static function scan($path, $options = []) { $options = array_merge([ 'callback' => null, // 對查找到的文件進行操做 'filterExt' => [], // 要過濾的文件後綴 ], $options); $scanQueue = [$path]; while (count($scanQueue) != 0) { $rootPath = array_pop($scanQueue); // 過濾['.', '..']目錄 $paths = array_filter(scandir($rootPath), function ($path) { return !in_array($path, ['.', '..']); }); foreach ($paths as $path) { // 拼接完整路徑 $fullPath = $rootPath . DIRECTORY_SEPARATOR . $path; // 若是是目錄的話,合併到掃描隊列中繼續進行掃描 if (is_dir($fullPath)) { array_unshift($scanQueue, $fullPath); continue; } // 若是不是空,進行過濾 if (!empty($options['filterExt'])) { $pathInfo = pathinfo($fullPath); $ext = $pathInfo['extension'] ?? null; if (in_array($ext, $options['filterExt'])) { continue; } } if ($options['callback'] instanceof Closure) { // 通過callback處理以後爲空的數據不做處理 $fullPath = $options['callback']($fullPath); // 返回的只要不是字符串路徑,不做處理 if (!is_string($fullPath)) { continue; } } array_push(static::$files, $fullPath); } } return static::$files; } /** * 目錄拷貝,返回被拷貝的文件數, * @param $source string 源文件,填寫絕對路徑 * @param $dest string 目標路徑,填寫絕對路徑 * @param $force bool 開啓會每次強制覆蓋原文件,false不進行覆蓋,存在文件不作處理 * @return int 拷貝的文件數 * @author: Vencenty */ static function copy($source, $dest, $force = true) { static $counter = 0; $paths = array_filter(scandir($source), function ($file) { return !in_array($file, ['.', '..']); }); foreach ($paths as $path) { // 要拷貝的源文件的完整路徑 $sourceFullPath = $source . DIRECTORY_SEPARATOR . $path; // 要拷貝到的文件的路徑 $destFullPath = $dest . DIRECTORY_SEPARATOR . $path; // 拷貝的目標地址若是是否是文件夾,那麼說明文件夾不存在,那麼首先建立文件夾 if (is_dir($sourceFullPath)) { if (!is_dir($destFullPath)) { mkdir($destFullPath); chmod($destFullPath, 0755); } // 遞歸copy static::copy($sourceFullPath, $destFullPath, $force); continue; } // 不開啓強制覆蓋的話若是已經存在文件了那麼直接跳過,不進行處理 if (!$force && file_exists($destFullPath)) { continue; } // 每次copy成功文件計數器+1 if (copy($sourceFullPath, $destFullPath)) { $counter++; } } return $counter; } } $path = realpath('../'); $r = Dir::scan($path, [ 'callback' => function ($file) { return filemtime($file) > strtotime('-1 day') ? $file : null; // 查找修改過的文件 }, 'filterExt' => [] ]); //print_r($r); $r = Dir::copy('C:\phpStudy\PHPTutorial\WWW\php\.idea', 'C:\phpStudy\PHPTutorial\WWW\php', true); print_r($r);
項目中須要使用這兩個功能,因此就寫了這兩個方法,其中scan
方法的第二個參數options
能夠根據本身的須要進行擴展,php
$r = Dir::scan($path, [ 'callback' => function ($file) { return filemtime($file) > strtotime('-1 day') ? $file : null; // 查找一天內修改過的文件 }, 'filterExt' => ['php'] // 過濾全部PHP文件 ]);
callback
回調函數能夠用來實現文件過濾的功能,文件類型查找等,具體場景具體分析options
參數至關因而擴展了函數配置項, 新的配置項會覆蓋默認配置,相較於一個函數ide
static function scan($path, $callback, $filterExt) {}
我更喜歡下面這種寫法,更靈活一些函數
static function scan($path, $options) { $options = array_merge([ 'callback' => null, 'filterExt' => [], 'otherOptions' => null ], $options); }
Dir::copy($source, $dest, $force = true)
這個函數也很簡單,就是帶了一個強制覆蓋和非強制覆蓋的選項,本身實現了一下,簡單記錄一下idea