PHP基于迭代實(shí)現(xiàn)文件夾復(fù)制、刪除、查看大小等操作的方法
本文實(shí)例講述了PHP基于迭代實(shí)現(xiàn)文件夾復(fù)制、刪除、查看大小等操作的方法。分享給大家供大家參考,具體如下:
前面一篇 PHP遞歸實(shí)現(xiàn)文件夾的復(fù)制、刪除、查看大小操作 分析了遞歸操作使用技巧,這里再來(lái)分析一下迭代的操作技巧。
“既然遞歸能很好的解決,為什么還要用迭代呢”?主要的原因還是效率問(wèn)題……
遞歸的概念是函數(shù)調(diào)用自身,把一個(gè)復(fù)雜的問(wèn)題分解成與其相似的多個(gè)子問(wèn)題來(lái)解決,可以極大的減少代碼量,使得程序看起來(lái)非常優(yōu)雅。
由于系統(tǒng)要為每次函數(shù)調(diào)用分配運(yùn)行空間,并使用壓棧予以記錄。在函數(shù)調(diào)用結(jié)束后,系統(tǒng)需要釋放空間,并彈?;謴?fù)斷點(diǎn)。所以遞歸的消耗還是比較大的。
即使語(yǔ)言設(shè)計(jì)時(shí)已經(jīng)將函數(shù)調(diào)用優(yōu)化的極度完美,達(dá)到可以忽略遞歸造成的資源浪費(fèi),但是遞歸的深度仍然會(huì)受到系統(tǒng)棧容量的限制,否則將會(huì)拋出 StackOverflowError 錯(cuò)誤。
而迭代能很好的利用計(jì)算機(jī)適合做重復(fù)操作的特點(diǎn),并且從理論上說(shuō),所有的遞歸函數(shù)都可以轉(zhuǎn)換為迭代函數(shù),所以盡量能不用遞歸就不用遞歸,能用迭代代替就用迭代代替。
查看文件夾大小
迭代的思路是讓計(jì)算機(jī)對(duì)一組指令進(jìn)行重復(fù)執(zhí)行,在每次執(zhí)行這組指令時(shí),都從變量的原值推出其它的新值……重復(fù)這一過(guò)程直到達(dá)到結(jié)束條件或沒(méi)有新值產(chǎn)生。
由于遞歸相當(dāng)于循環(huán)加堆棧,所以可以在迭代中使用堆棧來(lái)進(jìn)行遞歸和迭代的轉(zhuǎn)換。
/**
* 文件夾大小
* @param $path
* @return int
*/
function dirsize($path)
{
/* 初始條件 */
$size = 0;
$stack = array();
if (file_exists($path)) {
$path = realpath($path) . '/';
array_push($stack, '');
} else {
return -1;
}
/* 迭代條件 */
while (count($stack) !== 0) {
$dir = array_pop($stack);
$handle = opendir($path . $dir);
/* 執(zhí)行過(guò)程 */
while (($item = readdir($handle)) !== false) {
if ($item == '.' || $item == '..') continue;
$_path = $path . $dir . $item;
if (is_file($_path)) $size += filesize($_path);
/* 更新條件 */
if (is_dir($_path)) array_push($stack, $dir . $item . '/');
}
closedir($handle);
}
return $size;
}
復(fù)制文件夾
迭代和遞歸都具有初始化變量、判斷結(jié)束條件、執(zhí)行實(shí)際操作、產(chǎn)生新變量這四個(gè)步驟,只不過(guò)所在的位置不同罷了。
比如初始化變量這一步驟,在迭代中是位于函數(shù)的開(kāi)始部分,而在遞歸中是指其他函數(shù)傳遞參數(shù)這一過(guò)程;
判斷結(jié)束條件這一步驟,在迭代中用于判斷循環(huán)是否繼續(xù),在遞歸中用于判斷遞歸的結(jié)束位置;
執(zhí)行實(shí)際操作在遞歸和迭代中都是函數(shù)的核心部分,位于產(chǎn)生新變量步驟之前;
產(chǎn)生新變量在迭代中是迭代繼續(xù)的條件,在遞歸中是下一次遞歸的基礎(chǔ),由于產(chǎn)生了新變量才使得遞歸或迭代繼續(xù)進(jìn)行。
/**
* 復(fù)制文件夾
* @param $source
* @param $dest
* @return string
*/
function copydir($source, $dest)
{
/* 初始條件 */
$stack = array();
$target = '';
if (file_exists($source)) {
if (!file_exists($dest)) mkdir($dest);
$source = realpath($source) . '/';
$dest = realpath($dest) . '/';
$target = realpath($dest);
array_push($stack, '');
}
/* 迭代條件 */
while (count($stack) !== 0) {
$dir = array_pop($stack);
$handle = opendir($source . $dir);
if (!file_exists($dest . $dir)) mkdir($dest . $dir);
/* 執(zhí)行過(guò)程 */
while (($item = readdir($handle)) !== false) {
if ($item == '.' || $item == '..') continue;
$_source = $source . $dir . $item;
$_dest = $dest . $dir . $item;
if (is_file($_source)) copy($_source, $_dest);
/* 更新條件 */
if (is_dir($_source)) array_push($stack, $dir . $item . '/');
}
closedir($handle);
}
return $target;
}
刪除文件夾
拋開(kāi)語(yǔ)言特性影響性能最多的就是冗余代碼了,冗余代碼通常是由于設(shè)計(jì)不到位而產(chǎn)生的。
多數(shù)情況下遞歸要比迭代冗余代碼更多,這也是造成遞歸效率低的一大因素。
但當(dāng)遞歸代碼足夠簡(jiǎn)練,冗余度足夠低時(shí),迭代的性能未必就比遞歸高。
比如這個(gè)用迭代實(shí)現(xiàn)的文件夾刪除函數(shù),速度就比遞歸要慢20%,主要原因是空文件夾的判斷,在遞歸中當(dāng)文件夾沒(méi)有子文件夾時(shí),函數(shù)會(huì)直接刪除所有文件和當(dāng)前文件夾,遞歸結(jié)束。
在迭代中即使文件夾為空也需要將其存入堆棧,下次迭代時(shí)再判斷是否為空,之后才能刪除。這就相比遞歸多了判斷文件為空、存入堆棧、取出迭代等冗余操作,所以處理速度會(huì)比遞歸更慢。
/**
* 刪除文件夾
* @param $path
* @return bool
*/
function rmdirs($path)
{
/* 初始化條件 */
$stack = array();
if (!file_exists($path)) return false;
$path = realpath($path) . '/';
array_push($stack, '');
/* 迭代條件 */
while (count($stack) !== 0) {
$dir = end($stack);
$items = scandir($path . $dir);
/* 執(zhí)行過(guò)程 */
if (count($items) === 2) {
rmdir($path . $dir);
array_pop($stack);
continue;
}
/* 執(zhí)行過(guò)程 */
foreach ($items as $item) {
if ($item == '.' || $item == '..') continue;
$_path = $path . $dir . $item;
if (is_file($_path)) unlink($_path);
/* 更新條件 */
if (is_dir($_path)) array_push($stack, $dir . $item . '/');
}
}
return !(file_exists($path));
}
查看執(zhí)行時(shí)間
這是一個(gè)查看代碼執(zhí)行時(shí)間(毫秒數(shù))的函數(shù),通過(guò)回調(diào)方式執(zhí)行目標(biāo)代碼(或函數(shù)),最終計(jì)算出執(zhí)行的時(shí)間(毫秒)。通過(guò)這個(gè)工具可以對(duì)比函數(shù)之間的性能差距,非常簡(jiǎn)單實(shí)用的一個(gè)小工具。
/**
* 函數(shù)執(zhí)行毫秒數(shù)
* @param $func
* @return int
*/
function exec_time($func)
{
$start = explode(' ', microtime());
$func();// 執(zhí)行耗時(shí)操作
$end = explode(' ', microtime());
$sec_time = floatval($end[0]) - floatval($start[0]);
$mic_time = floatval($end[1]) - floatval($start[1]);
return intval(($sec_time + $mic_time) * 1000);
}
echo exec_time(function () {
/* 執(zhí)行的耗時(shí)操作 */
});
更多關(guān)于PHP相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《PHP目錄操作技巧匯總》、《php文件操作總結(jié)》、《PHP常用遍歷算法與技巧總結(jié)》、《PHP數(shù)據(jù)結(jié)構(gòu)與算法教程》、《php程序設(shè)計(jì)算法總結(jié)》、《PHP數(shù)組(Array)操作技巧大全》及《php字符串(string)用法總結(jié)》
希望本文所述對(duì)大家PHP程序設(shè)計(jì)有所幫助。
- PHP遞歸實(shí)現(xiàn)文件夾的復(fù)制、刪除、查看大小操作示例
- PHP文件及文件夾操作之創(chuàng)建、刪除、移動(dòng)、復(fù)制
- PHP創(chuàng)建/刪除/復(fù)制文件夾、文件
- PHP實(shí)現(xiàn)遞歸復(fù)制整個(gè)文件夾的類實(shí)例
- php刪除與復(fù)制文件夾及其文件夾下所有文件的實(shí)現(xiàn)代碼
- PHP操作文件類的函數(shù)代碼(文件和文件夾創(chuàng)建,復(fù)制,移動(dòng)和刪除)
- 探討PHP刪除文件夾的三種方法
- PHP 刪除文件與文件夾操作 unlink()與rmdir()這兩個(gè)函數(shù)的使用
- php定時(shí)刪除文件夾下文件(清理緩存文件)
- php刪除文件夾及其文件夾下所有文件的函數(shù)代碼
- php使用遞歸與迭代實(shí)現(xiàn)快速排序示例
相關(guān)文章
php使用Jpgraph創(chuàng)建柱狀圖展示年度收支表效果示例
這篇文章主要介紹了php使用Jpgraph創(chuàng)建柱狀圖展示年度收支表效果,結(jié)合完整實(shí)例形式分析了Jpgraph創(chuàng)建柱狀圖的具體步驟與操作技巧,需要的朋友可以參考下2017-02-02
PHP date_default_timezone_set()設(shè)置時(shí)區(qū)操作實(shí)例分析
這篇文章主要介紹了PHP date_default_timezone_set()設(shè)置時(shí)區(qū)操作,結(jié)合實(shí)例形式分析了PHP使用date_default_timezone_set()設(shè)置時(shí)區(qū)相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下2020-05-05
談PHP生成靜態(tài)頁(yè)面分析 模板+緩存+寫(xiě)文件
談PHP生成靜態(tài)頁(yè)面 模板+緩存+寫(xiě)文件,大家可以參考下代碼。2009-08-08
php代碼書(shū)寫(xiě)習(xí)慣優(yōu)化小結(jié)
本篇文章是對(duì)php代碼書(shū)寫(xiě)習(xí)慣優(yōu)化進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06
php返回相對(duì)時(shí)間(如:20分鐘前,3天前)的方法
這篇文章主要介紹了php返回相對(duì)時(shí)間的方法,可實(shí)現(xiàn)返回如:20分鐘前、3天前等格式時(shí)間,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04
PHP入門(mén)教程之?dāng)?shù)學(xué)運(yùn)算技巧總結(jié)
這篇文章主要介紹了PHP入門(mén)教程之?dāng)?shù)學(xué)運(yùn)算技巧,結(jié)合實(shí)例形式總結(jié)分析了php數(shù)值運(yùn)算、變量檢測(cè)、隨機(jī)數(shù)、絕對(duì)值、取整、最大值、最小值、四舍五入等操作技巧,需要的朋友可以參考下2016-09-09
解決form中action屬性后面?傳遞參數(shù) 獲取不到的問(wèn)題
下面小編就為大家?guī)?lái)一篇解決form中action屬性后面?傳遞參數(shù) 獲取不到的問(wèn)題。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-07-07

