I'm trying to move a folder by renaming it. Both the test1 and test2 folders already exist.
rename(
"test1",
"test2/xxx1/xxx2"
);
The error I get is: rename(...): No such file or directory
I assume this is because the directory "xxx1" does not exist.
How can I move the test1 directory anyway?
You might need to create the directory it is going into, e.g.
$toName = "test2/xxx1/xxx2";
if (!is_dir(dirname($toName))) {
mkdir(dirname($toName), 0777, true);
}
rename("test1", $toName);
The third parameter to mkdir()
is 'recursive', which means you can create nested directories with one call.
Why not make sure all parent directories exist first, by making them? mkdir - use the recursive parameter.
Your assumption was correct, this is because "xxx1" in your example does not exist.
So, before rename("oldname", "/some/long/nested/path/test2/xxx1/newname")
you have to create directory tree structure: /some/long/nested/path/test2/xxx1/
but newname
file (or directory) must not exist at the moment of rename
function call.
To generalize the solution look at the following naive function:
function renameWithNestedMkdir($oldname , $newname)
{
$targetDir = dirname($newname); // Returns a parent directory's path (operates naively on the input string, and is not aware of the actual filesystem)
// here $targetDir is "/some/long/nested/path/test2/xxx1"
if (!file_exists($targetDir)) {
mkdir($targetDir, 0777, true); // third parameter "true" allows the creation of nested directories
}
return rename($oldname , $newname);
}
// example call
renameWithNestedMkdir("oldname", "/some/long/nested/path/test2/xxx1/newname");
// another example call
renameWithNestedMkdir("test1", "test2/xxx1/xxx2");
I named this implementation "naive" because in real production you should also think about handling some edge cases: what if $newname already exists? What if /some/long/nested/path/test2/xxx1
already exists but it's a file (not a directory)? Why I put 0777 access rights while mkdir? What if mkdir failed?
I think test2/xxx1 would need to exist, so you'd need to use mkdir before you move it.