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

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

后臺站點(diǎn)文件掃描

2019-11-14 11:56:43
字體:
供稿:網(wǎng)友

前言遍歷文件scandir給定目錄非法使用dir函數(shù)遞歸法路徑解析數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)原理解析代碼實(shí)現(xiàn)演示當(dāng)前目錄父級目錄總結(jié)

前言

這幾天在看easyui,看到樹形結(jié)構(gòu)這個(gè)組件的時(shí)候突發(fā)奇想,能不能把站點(diǎn)以目錄樹的形式展示呢?

然后著手實(shí)現(xiàn)了一下,具體的來說是實(shí)現(xiàn)了對數(shù)據(jù)層的獲取,還沒有附加到tree組件上。下面就來談?wù)勎覍@次文件信息抓取的體會吧。

遍歷文件

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

scandir

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

空口無憑,找個(gè)實(shí)例來看一下就一目了然了。

給定目錄

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

效果如下 正常解析目錄

非法使用

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

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

非法使用場景

所以,使用scandir函數(shù)的時(shí)候務(wù)必明確這一點(diǎn),傳正確的參數(shù)!!!

dir函數(shù)

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

<?php/** * Created by PhpStorm. * User: ${郭璞} * Date: 2017/2/3 * Time: 20:25 * Description: scandir函數(shù)測試 */$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'。將出現(xiàn)如下結(jié)果。 dir函數(shù)處理非目錄信息

當(dāng)然,這兩個(gè)方法都沒能實(shí)現(xiàn)我們想要的效果。不能突破子目錄的情況,沒辦法遍歷到最底層的文件信息。

遞歸法

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

使用面向過程的PHP編碼方法需要處理外部數(shù)組引用問題,顯得代碼不是很容易理解,所以我選擇面向?qū)ο蟮姆椒ǎ瑢⑼獠繑?shù)組封裝到一個(gè)類中,專門用于處理這類問題。

<?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(); } /** * 去除路徑設(shè)置信息,析構(gòu)方法 */ 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; }}

下面是測試時(shí)使用的代碼。

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

最終實(shí)現(xiàn)的效果為: 遞歸效果實(shí)現(xiàn)目錄遍歷

路徑解析

單單是這樣,不是很好用。我就想著能不能實(shí)現(xiàn)類似于Python中os.walk那樣優(yōu)雅的獲取相關(guān)的信息呢?

數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)

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

但是我這邊為了以后使用easyui的tree組件,可能需要處理一下目錄深度的問題,所以我設(shè)計(jì)了下面的數(shù)據(jù)結(jié)構(gòu)。比較簡單,但是實(shí)用性感覺還是挺強(qiáng)的。

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

原理解析

我個(gè)人認(rèn)為原理還是比較簡單的了,那就是以文件分隔符作為計(jì)算標(biāo)準(zhǔn)。當(dāng)然了,需要處理一大堆的路徑適配問題,尤其是./../這樣的相對路徑。

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

代碼實(shí)現(xiàn)

class PathParser{ PRivate $patharray; private $resultSet; public function __construct($patharray) { // 從外部獲取到處理結(jié)果集 $this->patharray = $patharray; // 初始化結(jié)果集數(shù)組 $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]; //計(jì)算level $fileinfo->level = $this->parseLavel($fileinfo->fullpath);// echo $fileinfo->level."<------->"; // 計(jì)算經(jīng)過的路徑并進(jìn)行存儲 $fileinfo->pathstep = $this->parseStep($fileinfo->fullpath);// echo $fileinfo->pathstep."<br />";// var_dump($fileinfo->pathstep); array_push($this->resultSet, $fileinfo); } //返回計(jì)算結(jié)果,整體作為結(jié)果集返回 return $this->resultSet; } /** * 獲取給定路徑所經(jīng)過的路徑的結(jié)果集,將用于分級目錄展示 * @param $fileinfo * @return int */ public function parseStep($fileinfo) { if(!$fileinfo) { echo "<mark>".$fileinfo." path error!</mark>"; exit(); } // 判斷是否為相對路徑是的話去掉第一級目錄。 啊好煩,windows上和linux上差別還這么大,怎么處理好呢。。。 // 還是按照文件在服務(wù)器上的位置來進(jìn)行來處理好了。判斷是不是相對路徑然后再針對“路徑分隔符”計(jì)算路徑的level if($this->isRelativePath($fileinfo) == 1) { // 相對路徑處理 // 去掉相對路徑符號 $fileinfo = substr($fileinfo,2, strlen($fileinfo)); // 按照目錄分隔符 作為切割標(biāo)準(zhǔn),結(jié)果就是路徑本身包含的路徑信息 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(); } //按照文件在服務(wù)器上的位置來進(jìn)行來處理好了。判斷是不是相對路徑然后再針對“路徑分隔符”計(jì)算路徑的level if($this->isRelativePath($fileinfo) == 1) { // 相對路徑處理 // 去掉當(dāng)前相對路徑符號 $fileinfo = substr($fileinfo,2, strlen($fileinfo)); // 通過計(jì)算 路徑分隔符來作為level的判斷標(biāo)準(zhǔn)// 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)) { // 絕對路徑處理 // 算了,先不做這塊了,貌似偏離了我這個(gè)需求。 }else{ // 文件路徑非法 echo "<mark>".$fileinfo." 文件路徑非法</mark>"; exit(); } } /** * 判斷是否為相對路徑 * @param $path * @return bool * */ private function isRelativePath($path) { // 父級目錄擁有更高的優(yōu)先級 $prefix = substr($path, 0, 3); if($prefix == "../") { return 2; } // 處理 當(dāng)前目錄情況 $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; } }}

演示

下面演示一下實(shí)現(xiàn)的效果吧。

當(dāng)前目錄

測試代碼如下

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

結(jié)果圖 當(dāng)前目錄信息獲取

父級目錄

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

結(jié)果還行吧。我看著挺詳細(xì)的了。那么到這里就差不多實(shí)現(xiàn)預(yù)期的效果了。

總結(jié)

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

顯示通過通用的scandir 函數(shù)和dir循環(huán)讀取方式對目錄進(jìn)行了讀取,但是效果不佳,于是轉(zhuǎn)戰(zhàn)遞歸實(shí)現(xiàn)。

為了達(dá)到一個(gè)更加優(yōu)雅的信息獲取效果,又設(shè)計(jì)了一個(gè)專門針對于文件的類,用于存儲相關(guān)數(shù)據(jù)。

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

缺點(diǎn)嘛,顯而易見。代碼的風(fēng)格不是很好,命名什么的也是按照我自己的套路來的,不是很正規(guī)。

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


發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 凤山市| 吴桥县| 呼和浩特市| 竹山县| 广宁县| 瓦房店市| 晋中市| 武宁县| 砚山县| 北票市| 涿鹿县| 浦江县| 临沭县| 湟中县| 岑巩县| 永寿县| 海阳市| 行唐县| 湘潭县| 潢川县| 剑川县| 土默特右旗| 泸州市| 集贤县| 平南县| 同仁县| 儋州市| 南乐县| 聊城市| 肥城市| 九江县| 宣化县| 边坝县| 广汉市| 商丘市| 会东县| 民丰县| 广丰县| 海阳市| 大连市| 公安县|