国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

后臺站點文件掃描

2019-11-14 12:30:27
字體:
來源:轉載
供稿:網友

前言遍歷文件scandir給定目錄非法使用dir函數遞歸法路徑解析數據結構設計原理解析代碼實現演示當前目錄父級目錄總結

前言

這幾天在看easyui,看到樹形結構這個組件的時候突發奇想,能不能把站點以目錄樹的形式展示呢?

然后著手實現了一下,具體的來說是實現了對數據層的獲取,還沒有附加到tree組件上。下面就來談談我對這次文件信息抓取的體會吧。

遍歷文件

php中遍歷文件有很多方式,但是適用的場景不盡相同。所以在合適的場合適用合適的方法顯得至關重要,下面簡要的了解一下。

scandir

如果說想找到一款類似于Python中使用os.walk獲取文件目錄信息的優雅的方法,在PHP中就不是那么的方便了,唯一能稱得上簡單的就是scandir函數,但是這個函數并不優雅,其作用就是掃描給定目錄下的文件信息(如果包含子目錄,那就只能顯示到子目錄的層級,再想查看子目錄下的信息,那就不行了,否則會報錯的)。

空口無憑,找個實例來看一下就一目了然了。

給定目錄

<?php/** * Created by PhpStorm. * User: ${郭璞} * Date: 2017/2/3 * Time: 20:25 * Description: scandir函數測試 */$pathinfo = scandir('.');var_dump($pathinfo);

效果如下 正常解析目錄

非法使用

所謂非法使用,就是指給出非目錄文件時的場景,比如我們直接給個文件的路徑,就是這樣了。

<?php/** * Created by PhpStorm. * User: ${郭璞} * Date: 2017/2/3 * Time: 20:25 * Description: scandir函數測試 */$pathinfo = scandir('./scandir.php');var_dump($pathinfo);

非法使用場景

所以,使用scandir函數的時候務必明確這一點,傳正確的參數?。?!

dir函數

既然使用scandir函數不行了,那咱們就換個思路唄。下面介紹一個比較常用的方法。

<?php/** * Created by PhpStorm. * User: ${郭璞} * Date: 2017/2/3 * Time: 20:25 * Description: scandir函數測試 */$path = ".";if(is_dir($path)) { $dirinfo = dir($path); while($file = $dirinfo->read()) { echo "<mark>".$file."</mark><br />"; } $dirinfo->close();}else if (is_file($path)) { echo "<font color='green'>".$path."</font>";}

獲取指定目錄下文件信息

如果將$path='.'換成$path='./scandir.php'。將出現如下結果。 dir函數處理非目錄信息

當然,這兩個方法都沒能實現我們想要的效果。不能突破子目錄的情況,沒辦法遍歷到最底層的文件信息。

遞歸法

既然如此,那就得另尋他法了。我個人覺得遞歸的方法不賴,應該可以靈活地處理這些問題,說做就做。

使用面向過程的PHP編碼方法需要處理外部數組引用問題,顯得代碼不是很容易理解,所以我選擇面向對象的方法,將外部數組封裝到一個類中,專門用于處理這類問題。

<?php/** * Created by PhpStorm. * User: ${郭璞} * Date: 2017/2/3 * Time: 9:32 * Description: 讀取給定目錄及子目錄下文件路徑信息 */class FileWatcher{ public $fileinfo; /** * FileWatcher constructor. * @param $path 給定路徑 */ function __construct(){ $this->fileinfo = array(); } /** * 去除路徑設置信息,析構方法 */ function __destruct() { // TODO: Implement __destruct() method. $this->fileinfo = null; } public function scanDir($path) { if(is_dir($path)) { $tmpdir = dir($path); while($tmpfile = $tmpdir->read()) { if($tmpfile!='.' && $tmpfile!='..') $this->scanDir($path."/".$tmpfile); } $tmpdir->close(); } if(is_file($path)) { array_push($this->fileinfo, $path); } return $this->fileinfo; }}

下面是測試時使用的代碼。

$fileWatcher = new FileWatcher();$result = $fileWatcher->scanDir('.');var_dump($result);

最終實現的效果為: 遞歸效果實現目錄遍歷

路徑解析

單單是這樣,不是很好用。我就想著能不能實現類似于Python中os.walk那樣優雅的獲取相關的信息呢?

數據結構設計

使用過那個方法的應該都了解,獲取到的元組信息非常的詳細,包括路徑啊,目錄級啊什么的非常的詳細。

但是我這邊為了以后使用easyui的tree組件,可能需要處理一下目錄深度的問題,所以我設計了下面的數據結構。比較簡單,但是實用性感覺還是挺強的。

class FileInfo{ // 目錄深度 public $level; // 文件經過的路徑,以數組形勢依次填充 public $pathstep; // 文件的完整路徑 public $fullpath; public function __construct() { //pathstep 存儲當前路徑經過的文件夾信息 $this->pathstep = array(); } public function __destruct() { // TODO: Implement __destruct() method. $this->pathstep = null; $this->level = null; $this->fullpath = null; }}

原理解析

我個人認為原理還是比較簡單的了,那就是以文件分隔符作為計算標準。當然了,需要處理一大堆的路徑適配問題,尤其是./../這樣的相對路徑。

處理完這些之后就輕松多了,使用explode函數將字符串進行分割,裝填到數組中即可。

代碼實現

class PathParser{ PRivate $patharray; private $resultSet; public function __construct($patharray) { // 從外部獲取到處理結果集 $this->patharray = $patharray; // 初始化結果集數組 $this->resultSet = array(); // bean類對象 $this->fileinfo = new FileInfo(); } public function __destruct() { // TODO: Implement __destruct() method. $this->resultSet = null; $this->level = null; $this->fullpath = null; } public function parse() { for ($index=0; $index<count($this->patharray); $index++) { // 賦予完整路徑 $fileinfo = new FileInfo(); $fileinfo->fullpath = $this->patharray[$index]; //計算level $fileinfo->level = $this->parseLavel($fileinfo->fullpath);// echo $fileinfo->level."<------->"; // 計算經過的路徑并進行存儲 $fileinfo->pathstep = $this->parseStep($fileinfo->fullpath);// echo $fileinfo->pathstep."<br />";// var_dump($fileinfo->pathstep); array_push($this->resultSet, $fileinfo); } //返回計算結果,整體作為結果集返回 return $this->resultSet; } /** * 獲取給定路徑所經過的路徑的結果集,將用于分級目錄展示 * @param $fileinfo * @return int */ public function parseStep($fileinfo) { if(!$fileinfo) { echo "<mark>".$fileinfo." path error!</mark>"; exit(); } // 判斷是否為相對路徑是的話去掉第一級目錄。 啊好煩,windows上和linux上差別還這么大,怎么處理好呢。。。 // 還是按照文件在服務器上的位置來進行來處理好了。判斷是不是相對路徑然后再針對“路徑分隔符”計算路徑的level if($this->isRelativePath($fileinfo) == 1) { // 相對路徑處理 // 去掉相對路徑符號 $fileinfo = substr($fileinfo,2, strlen($fileinfo)); // 按照目錄分隔符 作為切割標準,結果就是路徑本身包含的路徑信息 return explode("/", $fileinfo); }else if($this->isRelativePath($fileinfo) == 2){ $fileinfo = substr($fileinfo, 3, strlen($fileinfo)); return explode("/", $fileinfo); }else if ($this->isAbsolutePath($fileinfo)) { // 絕對路徑處理 }else{ // 文件路徑非法 echo "<mark>".$fileinfo." 文件路徑非法</mark>"; exit(); } } public function parseLavel($fileinfo) { if(!$fileinfo) { echo "<mark>".$fileinfo." path error!</mark>"; exit(); } //按照文件在服務器上的位置來進行來處理好了。判斷是不是相對路徑然后再針對“路徑分隔符”計算路徑的level if($this->isRelativePath($fileinfo) == 1) { // 相對路徑處理 // 去掉當前相對路徑符號 $fileinfo = substr($fileinfo,2, strlen($fileinfo)); // 通過計算 路徑分隔符來作為level的判斷標準// echo "<mark>".count(explode("/", $fileinfo))."</mark>"; return count(explode("/", $fileinfo)); }else if ($this->isRelativePath($fileinfo) == 2 ) { //去掉父級目錄信息 $fileinfo = substr($fileinfo, 3, strlen($fileinfo)); return count(explode("/", $fileinfo)); }else if ($this->isAbsolutePath($fileinfo)) { // 絕對路徑處理 // 算了,先不做這塊了,貌似偏離了我這個需求。 }else{ // 文件路徑非法 echo "<mark>".$fileinfo." 文件路徑非法</mark>"; exit(); } } /** * 判斷是否為相對路徑 * @param $path * @return bool * */ private function isRelativePath($path) { // 父級目錄擁有更高的優先級 $prefix = substr($path, 0, 3); if($prefix == "../") { return 2; } // 處理 當前目錄情況 $prefix = substr($path, 0, 2); if ($prefix == "./"){ return 1; }else{ return false; } } /** * 判斷給定路徑是否為絕對路徑 * @param $path * @return bool */ private function isAbsolutePath($path) { $prefix = substr($path, 0, 1); if($prefix=="/"){ return true; }else{ return false; } }}

演示

下面演示一下實現的效果吧。

當前目錄

測試代碼如下

//獲取全部文件以及路徑信息$fileWatcher = new FileWatcher();$result = $fileWatcher->scanDir('.');$pathParser = new PathParser($result);$resultSet = $pathParser->parse();echo json_encode($resultSet);

結果圖 當前目錄信息獲取

父級目錄

對于父級目錄信息獲取,也是非常方便的。之前網上下載了easyui的壓縮包,解壓后扔到了apache服務器上,下面來看看對這個大文件信息集的獲取情況吧。 測試代碼把路徑中的那個.改成../easyui即可。 父級目錄信息獲取

結果還行吧。我看著挺詳細的了。那么到這里就差不多實現預期的效果了。

總結

回顧一下,今天主要是對于文件目錄信息的遍歷。

顯示通過通用的scandir 函數和dir循環讀取方式對目錄進行了讀取,但是效果不佳,于是轉戰遞歸實現。

為了達到一個更加優雅的信息獲取效果,又設計了一個專門針對于文件的類,用于存儲相關數據。

為了處理相對路徑中本級目錄和父級目錄等特殊情況,又使用了substr和explode函數,最后封裝成了一個通用的類,效果還不錯。

缺點嘛,顯而易見。代碼的風格不是很好,命名什么的也是按照我自己的套路來的,不是很正規。

其他的貌似也沒什么了,那就先這樣好了。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 安图县| 绥棱县| 筠连县| 卓资县| 潮安县| 鲜城| 锡林浩特市| 弋阳县| 镇坪县| 青州市| 钟山县| 静宁县| 南昌市| 仙桃市| 桑植县| 金溪县| 射阳县| 沿河| 宜君县| 庆云县| 阳泉市| 炉霍县| 太湖县| 新巴尔虎右旗| 南通市| 精河县| 高邑县| 施甸县| 宁南县| 松滋市| 荣成市| 开封县| 芮城县| 潞城市| 礼泉县| 任丘市| 泸溪县| 长顺县| 山西省| 四平市| 徐闻县|