[摘要]!is_file(dst)) return this->error_occur(0x000B, __FUNCTION__); if (!is_readable(src))...
!is_file($dst)) return $this->error_occur(0x000B, __FUNCTION__);
if (!is_readable($src)) return $this->error_occur(0x0006, $src);
if (!is_readable($dst)) return $this->error_occur(0x0006, $dst);
$i = filesize($src);
if (filesize($dst)!=$i) { // 文件大小不等
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; // 文件 MD5 效验不符合,内容不相同
return TRUE;
}
/**
* @]Method Name[= copy()
* @]Purpose[=
* 对任意文件夹、文件进行复制,相对或绝对路径皆可,文件复制完成后会进行效验,检查是否出错数据错误
* @]Parameter[=
* string $src_path 指定要复制的源内容路径,文件或目录均可
* string $dst_path 指定要复制的目标内容路径,文件或目录均可,性质由 $src_path 决定,可为 $src_path 下层目录
* @]Return[= boolean 错误返回 FALSE,否则 TRUE
* @]Author[= SNakeVil <51JS,BU,PHPx> (snakevil@qq.com)
* @]See[=
*/
function copy($src="", $dst="", $sub=FALSE) {
if (!$src=realpath($src)) return $this->error_occur(0x000B, __FUNCTION__);
$dst = $this->generate_path($dst);
if (is_dir($src)) { // 处理目录
/*
* 关于算法的说明:
* 本来打算使用很简单的递归算法,遇神杀神,遇魔斩魔的,后来发现一个问题:如果目标路径
* 为源路径的后代路径怎么办?这样算法会不停的探测下去…
* 于是添加了 $this->exist_dir 属性,用来记录这一情况下目标路径中存在的部分。于是新的问
* 题出来了:如何保存这一属性?
* 将整个功能整合到 $this->copy() 方法中,那么必然需要在这个函数中记录 $this->exist_dir
* 的变化,于是乎需要另外的一个有效的方法来阻止每一次操作中对其的更改。
* 作为变通,我使用的隐藏参数 $sub,这个参数无论如何,只要算法不变,永远在参数表的最
* 后一个。因此,方法开始变得不稳定,但这也没有办法,只能希望程序员自己不要故意破坏。
* 在外部调用时,因为默认 FALSE,所以对 $this->exist_dir 写。内部递归时,显性 TRUE,不
* 该属性,保证有效性。
*/
if (!is_readable($src)) return $this->error_occur(0x0002, $src);
if ($dst[strlen($dst)-1]!=DIRECTORY_SEPARATOR) $dst .= DIRECTORY_SEPARATOR;
if (TRUE===$sub&&$src==$this->exist_dir) return TRUE; // 源路径为记录的目标路径
if (TRUE!==$sub) $this->exist_dir = ""; // 记录创建目录前目标目录路径中存在的目录路径
if (!$this->make_dir($dst)) return FALSE; // 创建目录
if (FALSE===$i=$this->list_dir($src)) return FALSE; // 读取目录出错
for ($j=0,$k=count($i);$j<$k;$j++) if (!$this->copy($i[$j]["location"], $dst.$i[$j]["name"],TRUE)) return FALSE;
unset($i, $j, $k);
RETURN TRUE;
} else {
if (!is_readable($src)) return $this->error_occur(0x0006, $src);
if ($this->verify_file($src,$dst)) return TRUE;
if (!copy($src,$dst)) return $this->error_occur(0x0007, $dst);
if (!$this->verify_file($src,$dst)) {
@unlink($dst); // 复制文件失败删除新文件
return $this->error_occur(0x0007, $dst);
}
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,PHPx> (snakevil@qq.com)
* @]See[=
*/
function move($src="", $dst="", $sub=FALSE) {
if (!$src=realpath($src)) return $this->error_occur(0x000B, __FUNCTION__);
$dst = $this->generate_path($dst);
if (is_dir($src)) { // 处理目录
if (!is_readable($src)) return $this->error_occur(0x0002, $src);
if ($dst[strlen($dst)-1]!=DIRECTORY_SEPARATOR) $dst .= DIRECTORY_SEPARATOR;
if (TRUE===$sub&&$src==$this->exist_dir) return TRUE;
if (TRUE!==$sub) $this->exist_dir = "";
if (!$this->make_dir($dst)) return FALSE;
if (FALSE===$i=$this->list_dir($src)) return FALSE;
for ($j=0,$k=count($i);$j<$k;$j++) if (!$this->move($i[$j]["location"], $dst.$i[$j]["name"],TRUE)) return FALSE;
unset($i, $j, $k);
if (FALSE===strpos($this->exist_dir,$src))
if (!@rmdir($src)) return $this->error_occur(0x0004, $src); // 对非目标目录的上层目录,删除
return TRUE;
} else {
if (!is_readable($src)) return $this->error_occur(0x0006, $src);
if ($this->verify_file($src,$dst)) return TRUE;
if (!copy($src,$dst)) return $this->error_occur(0x0007, $dst);
if (!$this->verify_file($src,$dst)) {
@unlink($dst);
return $this->error_occur(0x0007, $dst);
}
if (!@unlink($src)) return $this->error_occur(0x0006, $src); // 删除源文件
return TRUE;
}
}
/**
* @]Method Name[= no_comment()
* @]Purpose[=
* 清除文件中 C 规范的注释
* @]Parameter[=
* string $path 指定要执行操作的文件
* @]Return[= boolean 错误返回 FALSE,否则 TRUE
* @]Author[= SNakeVil <51JS,BU,PHPx> (snakevil@qq.com)
* @]See[=
*/
function no_comment($path="") {
if (!is_file($path)) return $this->error_occur(0x000B, __FUNCTION__);
if (!is_readable($path)) return $this->error_occur(0x0006, $path);
if (!is_writeable($path)) return $this->error_occur(0x0007, $path);
if (!$th=tmpfile()) return $this->error_occur(0x000C, $path); // 创建临时文件
$fh = fopen($path, "r+b");
if (!flock($fh,LOCK_EX)) { // 锁定文件
fclose($fh);
unset($fh);
return $this->error_occur(0x0009, $path);
}
$fbuffer = fread($fh, $this->buffer_size*2); // 文件读取缓冲区
$tbuffer = ""; // 临时文件缓冲区
$in_dq = $in_sq = $in_lc = $in_bc = FALSE;
while ($fblen=strlen($fbuffer)) { // 处理原始数据
$fstats = feof($fh);
for ($i=0;$i<$fblen;$i++) { // 分析文件内容
if (!$fstats&&$i+5>$fblen) break; // 文件未完全读取时临近缓冲区读取完成读取下一块文件内容
$j = substr($fbuffer, $i, 2);
$k = $j[0];
if ($j=="/*"&&!$in_dq&&!$in_sq&&!$in_lc) { // 不在字符串和行注释中,块注释开始
$in_bc = TRUE;
$i++;
} elseif ($j=="*/"&&$in_bc) { // 块注释结束
$in_bc = FALSE;
$i+=2;
} elseif ($j=="//"&&!$in_dq&&!$in_sq&&!$in_bc) { // 行注释开始
$in_lc = TRUE;
$i++;
} elseif ($in_lc&&($k=="\r"
关键词:PHP文件系统基本设置类