经过数日的研究和查阅其他优秀的示例,我尝试编写了一个递归移动函数。
它提供了一个overwriteExisting
选项。因此,如果overwriteExisting
选项为false
,文件将不会被移动,包含该文件的文件夹也不会被删除。
function moveRecursive($sourcePath, $targetPath, $overwriteExisting) {
clearstatcache(); // not sure if this helps, or is even required.
$dir = opendir($sourcePath);
while (($file = readdir($dir)) !== false) {
echo nl2br($file . "\n");
if ($file != "." && $file != "..") {
if (is_dir($sourcePath . "/" . $file) == true) {
if (is_dir($targetPath. "/" . $file) == false) {
// I believe rename would be faster than copying and unlinking.
rename($sourcePath . "/" . $file, $targetPath. "/" . $file);
} else {
moveRecursive($sourcePath . "/" . $file, $targetPath ."/" . $file, $overwriteExisting);
if ($files = glob($sourcePath . "/*")) {
// remove the empty directory.
if (@rmdir($sourcePath . "/" . $file) == false) {
echo nl2br("rmdir has not removed empty directory " . $sourcePath . "/" . $file . "\n");
}
} else {
// when overwriteExisting flag is false, there would be some files leftover.
echo nl2br("cannot remove. not empty, count = " . count(glob($sourcePath . "/*")) . " -> " . $sourcePath . "/" . $file . "\n");
}
}
} else {
if (file_exists($targetPath. "/" . $file)) {
if ($overwriteExisting == true) {
// overwrite the file.
rename($sourcePath . "/" . $file, $targetPath. "/" . $file);
}
} else {
// if the target file does not exist, simply move the file.
rename($sourcePath . "/" . $file, $targetPath. "/" . $file);
}
}
}
}
closedir($dir);
}
我已经花了大约3个小时在许多不同的场景下进行测试,大部分时间都是有效的。然而,有时在Windows上会给我一个"Access denied code(5)"错误,这是我无法解决的。这就是为什么我在阅读了它的文档后把"clearstatcache()"函数放在了顶部。我不知道这是否是适当的使用方式。我肯定可以想象它会减慢函数的速度。
我也可以想象这种方法可能比"copy -> unlink"循环更快,因为如果目标子文件夹不存在,整个文件夹树下面的所有内容都会被移动。但是,我不确定并且没有经验来进行详尽的测试。