views:

657

answers:

4

I've got a really annoying problem with file uploads.

Users can choose a file in an html file field. When they submit the form, this file will be uploaded.

On the serverside I just use standard PHP code (move_uploaded_file). I do nothing weird.

Everything works perfectly.

I can see the file on the server, I can download it again, ...

However sometimes this doesn't work. I upload the file, process it and I get no errors.

But the file just doesn't exist on the server.

Each time I upload that specific file I get no errors but it never gets saved.

Only if I rename it (test.file to tst.file for example) I can upload it and it'll actually get saved.

I get this problem very rarely. And renaming always works. But I can't ask users to rename their files obviously...

I have no access to the apache tmp file directory, no access to logs or settings so this makes debugging even harder. I only have this problem on this particular server (which I don't manage; I don't even have access to it) and I use the exact same code on lots of servers that don't have this problem.

I would be grateful if someone could help me out here or point me in the right direction.

+1  A: 

If an upload failes you don’t get the same kind of error like a PHP syntax error or such.

But you can check the file upload status and report the error to the user yourself.

Gumbo
Upload status is 0, which means the file should have been uploaded correctly.The problem could be a server problem and not a PHP problem.
+1  A: 

Trying adding this debug code:

echo '<pre>';
print_r($_FILES);
echo '</pre>';

You should see an error number. You can lookup what it means at http://uk3.php.net/manual/en/features.file-upload.errors.php

Might also be worth checking to make sure the destination file doesn't already exist.

James Hall
Upload status is 0, which means the file should have been uploaded correctly.The destination file does not already exist either.Everything works like it should, I get no errors but the file just doesn't exist.
+1  A: 

My first thought was filesize issues. In the php.ini, if the post_max_size or upload_max_filesize are too small, you can end up with similar results - where the file just seems to disappear. You would get an error in the apache logs (which you mention you've no access to).

In those cases, the $_FILES array would simply be empty - as if the file never arrived. Since your responses to Gumbo and James Hall show that php is reporting a proper upload, I'm led to wonder about the processing you mention.

If, during the process, your memory gets maxed or the script runs too long, the script may be dying out before it gets a chance to move it. You'll want to check these:

memory_limit

max_execution_time

max_input_time

Otherwise, without the apache logs, I'd say it might be a good idea to start outputting to a log file of your own throughout your file processing script. Try a file_exists on the tmp file, see what info you can get from the file (permissions, etc).

Unfortunately PHP doesn't get involved until the upload is finished, which means you won't get much info during - only after the fact. You best option might be to talk to the hosting company and get access to the logs - even if for a short time. In my experience, I've rarely had trouble getting ot the logs - or at least getting a tech to check the logs for me while I run tests (in the case where a shared server doesn't split their logs - seems ridiculous, but I've seen it before).

Edit: I realize you can't change those php settings, but you might want to see what they are in order to find out if they're potential problems for your script. For instance, a low memory limit will kill your processor script if it's less than the size of the uploaded file.

enobrev
i agree, he should check definitely check for the max size as the browser won't actually upload anything if file is larger than the max size.
dusoft
+1  A: 

This is what you said...

"I have no access to the apache tmp file directory, no access to logs or settings so this makes debugging even harder. I only have this problem on this particular server (which I don't manage; I don't even have access to it) and I use the exact same code on lots of servers that don't have this problem."

According to what you said above, I assume that you are using a server that is shared among many users. If the Apache of this server is configured with something like "mod_suphp", then your PHP scripts will be executed using the privileges of your UNIX user account ("jef1234", for example), which means the files you create will have you ("jef1234") as the owner (instead of "apache" or "www-data").

The system's temporary directory (usually "/tmp") is usually configured with the "sticky bit" on. This means everyone can create files in this directory, but the created files are only accessible by the owner (you may treat this as the one who created it).

As a result, if the server configuration is not careful enough, you may have file naming collisions with other users' files. For example, when you upload "test.file", if another user has already uploaded another file with the same name, the system refuses to overwrite the file created by him, as thus you have to use another name.

Usually the problem does not exist because PHP is smart enough to generate temporary names for the uploaded file (ie. $_FILES["html_form_input_name"]["tmp_name"]). If somehow you can confirm that this is really the reason, the server is obviously mis-configured. Tell your system administrator the problem as ask him to solve it. If this could not be solved, you may do some JavaScript tricks on the name of the file before it is uploaded (not tested, just an idea)...

When the user submits the form, rename the file from, for example, "test.file" to "jef1234-test.file-jef1234". After the file is uploaded, move the file (ie move_uploaded_file()) to another place and rename it to the original filename by removing the added strings.

Hope this helps...

Asuka Kenji

Siu Ching Pong - Asuka Kenji