Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Move a file and rename it

Figured PHP's rename would be my best bet. I didn't see many examples on how to use relative URLs in it though, so I kind of compromised. Either way, this give me permission denied:

I want to do this:

$file = "../data.csv";
rename("$file", "../history/newname.csv");

Where ../ of course would go back 1 directory from where the script is being ran. I couldn't figure out a way...so I did this instead:

$file = "data.csv";
$path = dirname(realpath("../".$file));
rename("$path/$file", "$path/history/newname.csv");

However I am getting permission denied (yes the history folder is owned by www-data, and yes data.csv is owned by www-data). I thought it was weird so I tried a simple test:

rename( 'tempfile.txt', 'tempfile2.txt' );

and I made sure www-data had full control over tempfile.txt...still got permission denied. Why? does the file your renaming it to have to exist? can you not rename like linux's mv? So I instead just copy() and unlink()?

like image 266
ParoX Avatar asked Jul 25 '10 23:07

ParoX


2 Answers

In order to move a file from "../" to "../history/", a process needs write permission to both "../" and "../history/".

In your example, you're obviously lacking write permission to "../". Permissions for the file being moved are not relevant, by the way.

like image 66
Marc Donges Avatar answered Nov 14 '22 17:11

Marc Donges


Not only ownership plays a role, but also file permissions. Make sure that the permissions are set up correctly on the source file and destination directory (e.g. chmod 644 data.csv).

Is www-data the same user as Apache?

Edit: Take care to provide existing, absolute paths to realpath(). Also beware of the following:

$path = dirname(realpath("../".$file));

This might yield nothing, because the file ../data.csv might not exist. I.e., the result of realpath() on a non-existent file is false.

Here's some code that might work better for you:

$file = "data.csv";
$path1 = realpath($file);
$path2 = realpath(dirname($file).'/..').'/history/newname.csv';
rename($path1, $path2);

You should be extremely careful that $file cannot be edited by the visitor, because he could change a request manipulate which file is renamed to where.

like image 20
Paul Lammertsma Avatar answered Nov 14 '22 18:11

Paul Lammertsma