My attempt at a recursive move function, after days of research and going through other excellent examples out there.
It provides for an overwriteExisting flag for choice. Consequently, if the overwriteExisting flag is false, the file will not be moved and the folder containing the file would not be removed.
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);
}
I have spent about 3 hours testing this in many different scenarios, and it works most of the time. Although, sometimes, it gives me an Access denied code(5) error on Windows, which I have been unable to figure out. This is why I have put the clearstatcache() function up at the top, after reading up on its documentation. I don't know whether this is its appropriate usage. I can definitely imagine that it would slow down the function.
I can also imagine that this method may be faster than the copy -> unlink cycle, because if a target sub-folder does not exist, the whole folder tree below would be just moved. However, I am not sure and don't have the experience to conduct exhaustive tests, yet.