Importance of move_uploaded_file in safe_mode environments
Quite some time ago I’ve came upon a new webhost called 8tt (they are gone now). In summary, they were a free web hosting service that provide you with PHP5, 1 MySQL database and a lot of space. There was not much special about them, in fact they are very much like your standard free web hosting service, they even have safe_mode turned ON. However that is nothing to complain about, because as a free service they have to watch out for the evil spammer guys that just want to abuse free things. Also many of the disabled features are not required by your day-to-day website, but it still does end up being a bummer when you do need them.
I was working on a script that required me to upload a file, check it’s contents/file type, and if everything went all right, I had to move it to it’s finally location. To save some time, I figured I will use the temporary location as given by PHP’s $_FILES[‘filename’][‘tmp_name’] for the checks. That worked perfectly on my computer, but when I uploaded the final copy on the Web hell broke loose. I kept getting an error about not being allowed to upload files via PHP due to permission problems.
At first I was afraid that I will have to scrap the whole project, but after a bit of thinking I remembered the move_uploaded_file() function. And behold, the following is said about it:
Note: move_uploaded_file() is both safe mode and open_basedir aware.
All I had to do is copy the file to another temporary location (make sure it is writable!) under a filename returned by the tempnam() function and do the processing on that.
There is another method that is even simpler, faster AND more transparent. Since the only problem I had was that I was not allowed to access the /tmp directory, I figured why not just change where the files are temporarily stored when uploaded. It turns out that it is possible and requires only one simple modification, changing the upload_tmp_dir ini setting by the following command:
Just insert it anywhere at the beginning of your PHP script and you are set to go.