2---------------------------------------- /**
 * @]Method Name[= delete()
 * @]Purpose[=
 *     删除指定对象,文件或文件夹——包括内含子目录和文件的非空文件夹
 * @]Parameter[=
 *     string $path 指定要删除的内容路径,文件或目录均可
 * @]Return[= boolean 错误返回 FALSE,否则 TRUE
 * @]Author[= SNakeVil<51JS,BU>([email protected])
 * @]See[=
 */
function delete($path="") {
if (!file_exists($path)) return $this->error_occur(0x0003, $path);
if (is_dir($path)) {
$path = str_replace("\\", "/", realpath($path));
$path = substr($path, -1)=="/" ? $path : $path."/";
$sub_list = array(array($path));
for ($i=0;$i<count($sub_list);$i++) { // 使用 COUNT($SUB_LIST) 动态判断长度,从而有可能无定长循环
if (!isset($sub_list[$i])) break; // 探索到最尽头,获得该目录下所有子目录列表,方便文件删除后删除目录
for ($j=0,$k=count($sub_list[$i]);$j<$k;$j++) {
$l = $this->list_dir($sub_list[$i][$j]);
if (!$l) return $this->error_occur("", $sub_list[$i][$j]);
$l = $l["list"];
for ($m=0,$n=count($l);$m<$n;$m++) {
$o = $l[$m]["locate"].$l[$m]["name"];
if ($l[$m]["type"]==0) $sub_list[$i+1][] = $o;
elseif (!@unlink($o)) return $this->error_occur(0x0004, $o); // 删除目录下的每一个文件
}
}
}
for($i=count($sub_list)-1;$i>=0;$i--) // 逆回删除目录
for ($j=0,$k=count($sub_list[$i]);$j<$k;$j++) // 删除每一个子目录直到指定目录
if (!@rmdir($sub_list[$i][$j])) return $this->error_occur(0x0005, $sub_list[$i][$j]);
unset($i, $j, $k, $l, $m, $n, $o, $sub_list);
return true;
} elseif (@unlink($path)) return true;
else return $this->error_occur(0x0004, $path);
} /**
 * @]Method Name[= realpath()
 * @]Purpose[=
 *     获取现有或不存在文件、目录的绝对地址
 * @]Parameter[=
 *     string $path 要获取地址的文件、目录现有相对、绝对地址
 * @]Return[= mixed 错误返回 FALSE,否则为获得的地址
 * @]Author[= SNakeVil<51JS,BU>([email protected])
 * @]See[=
 */
function realpath($path="") {
if ($path==""||!is_string($path)) return $this->error_occur(0x0007, $path);
$path = preg_replace("/(?<!^\w)[\\\:\*\?\"\<\>\|]/", "", str_replace("\\", "/", $path)); // 规范路径中多可能性的符号
if (substr($path,1,1)==":") return $path; // !!!! Win32 平台的绝对路径
elseif (substr($path,0,1)=="/") return substr(realpath("."), 0, 2).$path; // !!!! Win32 平台下的绝对路径转换
else {
if (substr($path,-1)=="/") $path = substr($path,0,-1); // 清除结尾可能的 / 符号
$path = preg_replace("/\/{2,}/", "/", $path); // 将 /// 诸如类似的相连符号简化为一个
$path = explode("/", $path); // 分割路径
$cur_path = explode("/", str_replace("\\", "/", realpath(".")));
for ($i=0,$j=count($path);$i<$j;$i++) {
if ($path[$i]=="..") array_pop($cur_path);
elseif ($path[$i]=="."||$path[$i]==str_repeat(".", strlen($path[$i]))) continue; // 忽略无用的相对路径地址 . 和 .... 等
else array_push($cur_path, $path[$i]);
}
$path = implode("/", $cur_path);
unset($cur_path);
return $path;
}
} /**
 * @]Method Name[= make_dir()
 * @]Purpose[=
 *     建立任意文件夹,相对或绝对路径皆可,深层建立亦可
 * @]Parameter[=
 *     string $path 要建立的最终目录路径
 * @]Return[= boolean 错误返回 FALSE,否则 TRUE
 * @]Author[= SNakeVil<51JS,BU>([email protected])
 * @]See[=
 */
function make_dir($path="") {
if (!$path=$this->realpath($path)) return false;
$path = explode("/", $path);
$i = array($path[0]);
for ($i=0,$j=count($path),$k=array(),$l="";$i<$j;$i++) {
array_push($k, $path[$i]);
$l = implode("/", $k);
if (!file_exists($l)) {
if ($this->last_exist_dir=="") $this->last_exist_dir = $l;
if (!@mkdir($l)) return $this->error_occur(0x0008, $l);
}
}
return true;
} /**
 * @]Method Name[= verify_file()
 * @]Purpose[=
 *     使用 MD5 算法比较两个文件是否相同
 * @]Parameter[=
 *     string $src 源文件路径
 *     string $dst 目标文件路径
 *     boolean $interal 对于超过 1MB 文件,设置 FALSE 省去 MD5 检验步骤,减轻服务器负担
 * @]Return[= boolean 错误返回 FALSE,否则 TRUE
 * @]Author[= SNakeVil<51JS,BU>([email protected])
 * @]See[=
 */
function verify_file($src="",$dst="",$interal=true) {
if (!file_exists($src)||!is_file($src)) return $this->error_occur(0x000A, $src);
if (!file_exists($dst)||!is_file($dst)) return $this->error_occur(0x000A, $dst);
$i = filesize($src);
if ($i!=filesize($dst)) {
unset($i);
return false;
}
if ($i>1024*1024*1024&&!$interal) { // 对于大于 1MB 的文件,如果不要求精确检查,跳过
unset($i);
return true;
}
unset($i);
if (md5_file($src)!=md5_file($dst)) return false;
return true;
}

解决方案 »

  1.   

    3---------------------------------------- /**
     * @]Method Name[= copy()
     * @]Purpose[=
     *     对任意文件夹、文件进行复制,相对或绝对路径皆可,文件复制完成后会进行效验,检查是否出错数据错误
     * @]Parameter[=
     *     string $src_path 指定要复制的源内容路径,文件或目录均可
     *     string $dst_path 指定要复制的目标内容路径,文件或目录均可,性质由 $src_path 决定,可为 $src_path 下层目录
     * @]Return[= boolean 错误返回 FALSE,否则 TRUE
     * @]Author[= SNakeVil<51JS,BU>([email protected])
     * @]See[=
     */
    function copy($src_path="",$dst_path="") {
    if (!file_exists($src_path)) return $this->error_occur(0x0003, $src_path);
    if (!$dst_path=$this->realpath($dst_path)) return false;
    if (is_dir($src_path)) {
    $this->last_exist_dir = ""; // 记录现行实际存在的目录
    if (!$this->make_dir($dst_path)) return false; // 建立目录失败
    $src_path = str_replace("\\", "/", realpath($src_path));
    $src_path = substr($src_path, -1)=="/" ? $src_path : $src_path."/";
    $sub_list = array(array($src_path));
    for ($i=0;$i<count($sub_list);$i++) {
    if (!isset($sub_list[$i])) break;
    for ($j=0,$k=count($sub_list[$i]);$j<$k;$j++) {
    $l = $this->list_dir($sub_list[$i][$j]);
    if (!$l) return $this->error_occur(0x0003, $sub_list[$i][$j]);
    $l = $l["list"];
    for ($m=0,$n=count($l);$m<$n;$m++) {
    $o = $l[$m]["locate"].$l[$m]["name"];
    if ($o==$this->last_exist_dir) continue; // 如果为上级目录向下级目录复制,防止死循环
    $p = str_replace(substr($src_path, 0, -1), $dst_path, $o);
    if ($l[$m]["type"]==0) {
    $sub_list[$i+1][] = $o;
    if (!$this->make_dir($p)) return false; // 对每一个子目录都予以建立
    } else { // 对每一个文件进行复制
    if ($this->verify_file($o, $p)) continue; // 如果目标与源完全相同,不再复制
    if (!copy($o,$p)||!$this->verify_file($o,$p)) return $this->error_occur(0x0009, $o);
    }
    }
    }
    }
    unset($i, $j, $k, $l, $m, $n, $o, $p, $sub_list);
    return true;
    } else {
    if (!is_readable($src_path)) return $this->error_occur(0x0006, $src_path);
    if ($this->verify_file($src_path,$dst_path)) return true;
    $i = strrpos($dst_path, "/");
    $dst_path = array(substr($dst_path, 0, $i), substr($dst_path, $i+1));
    unset($i);
    if (!$this->make_dir($dst_path[0])) return false;
    $dst_path = implode("/", $dst_path);
    if (!copy($src_path,$dst_path)||!$this->verify_file($src_path,$dst_path)) return $this->error_occur(0x0009, $src_path);
    return true;
    }
    } /**
     * @]Method Name[= move()
     * @]Purpose[=
     *     对任意文件夹、文件进行移动,相对或绝对路径皆可,文件移动完成后会进行效验,检查是否出错数据错误
     * @]Parameter[=
     *     string $src_path 指定要移动的源内容路径,文件或目录均可
     *     string $dst_path 指定要移动的目标内容路径,文件或目录均可,性质由 $src_path 决定,可为 $src_path 下层目录
     * @]Return[= boolean 错误返回 FALSE,否则 TRUE
     * @]Author[= SNakeVil<51JS,BU>([email protected])
     * @]See[=
     */
    function move($src_path="",$dst_path="") {
    if (!file_exists($src_path)) return $this->error_occur(0x0003, $src_path);
    if (!$dst_path=$this->realpath($dst_path)) return false;
    if (is_dir($src_path)) {
    $this->last_exist_dir = "";
    if (!$this->make_dir($dst_path)) return false;
    $src_path = str_replace("\\", "/", realpath($src_path));
    $src_path = substr($src_path, -1)=="/" ? $src_path : $src_path."/";
    $sub_list = array(array($src_path));
    for ($i=0;$i<count($sub_list);$i++) {
    if (!isset($sub_list[$i])) break;
    for ($j=0,$k=count($sub_list[$i]);$j<$k;$j++) {
    $l = $this->list_dir($sub_list[$i][$j]);
    if (!$l) return $this->error_occur(0x0003, $sub_list[$i][$j]);
    $l = $l["list"];
    for ($m=0,$n=count($l);$m<$n;$m++) {
    $o = $l[$m]["locate"].$l[$m]["name"];
    if ($o==$this->last_exist_dir) continue;
    $p = str_replace(substr($src_path, 0, -1), $dst_path, $o);
    if ($l[$m]["type"]==0) {
    $sub_list[$i+1][] = $o;
    if (!$this->make_dir($p)) return false;
    } else {
    if ($this->verify_file($o, $p)) continue;
    if (!copy($o,$p)||!$this->verify_file($o,$p)) return $this->error_occur(0x0009, $o);
    if (!@unlink($o)) return $this->error_occur(0x0004, $o);
    }
    }
    }
    }
    for($i=count($sub_list)-1;$i>=0;$i--)
    for ($j=0,$k=count($sub_list[$i]);$j<$k;$j++)
    if (strpos($this->last_exist_dir,$sub_list[$i][$j])!==false) continue; // 对移动目标目录的上层目录,不予考虑删除
    elseif (!@rmdir($sub_list[$i][$j])) return $this->error_occur(0x0005, $sub_list[$i][$j]);
    unset($i, $j, $k, $l, $m, $n, $o, $p, $sub_list);
    return true;
    } else {
    if (!is_readable($src_path)) return $this->error_occur(0x0006, $src_path);
    if ($this->verify_file($src_path,$dst_path)) return true;
    $i = strrpos($dst_path, "/");
    $dst_path = array(substr($dst_path, 0, $i), substr($dst_path, $i+1));
    unset($i);
    if (!$this->make_dir($dst_path[0])) return false;
    $dst_path = implode("/", $dst_path);
    if (!copy($src_path,$dst_path)||!$this->verify_file($src_path,$dst_path)) return $this->error_occur(0x0009, $src_path);
    if (@unlink($src_path)) return true;
    else return $this->error_occur(0x0004, $src_path);
    }
    } /**
     * @]Error List[=
     *     0x0001  指定目录不存在
     *     0x0002  指定目录无读取权限
     *     0x0003  找不到要删除的对象
     *     0x0004  指定文件无删除权限
     *     0x0005  指定目录无删除权限
     *     0x0006  指定文件无读取权限
     *     0x0007  realpath() 方法参数错误
     *     0x0008  指定目录无法创建
     *     0x0009  相关文件移动失败
     *     0x000A  verify_file() 方法参数非文件
     *     0x000B  指定文件不存在
     *     0x000C  指定文件无写入权限
     *     0x000D  指定文件无法锁定
     *     
     *     
     *     
     *     
     *     
     */----------------------------------------END