tags:

views:

62

answers:

1

I have some code that allows users to upload multiple files at once. It was never getting to a specific point after the upload, so I put in an echo to test for the value of the error code, and it's returning a value that I'm not sure I understand. Here's the code:

    $tmpTarget = PCBUG_UPLOADPATH;
    foreach ($_FILES["attachments"]["error"] as $key => $error) {
       if ($error == UPLOAD_ERR_OK) {
            $tmp_name = $_FILES["attachments"]["tmp_name"][$key];
            $name = str_replace(" ", "_", $_FILES["attachments"]["name"][$key]);
            move_uploaded_file($tmp_name, "$tmpTarget/$name");
            @unlink($_FILES["attachments"]["tmp_name"][$key]);
        }
        else {
            $errorFlag = true;
            echo "error = $error";
            exit;
        }
    }

The code that creates the attachments field looks like this:

for($i=1; $i<=$max_no_img; $i++){
    echo "<input type=file name='attachments[]' class='bginput'><br />";
}

where $max_no_img is a variable set further up in the code, and PCBUG_UPLOAD path is a constant defined in an included file.

Here's what's confusing: after I submit my form, I go and look in my uploads directory, and the files I've selected through the form are there - they uploaded correctly. However, the code is jumping into the else clause and $error is returning 4, which the php manual indicates means that no file was uploaded.

Any ideas? The files very clearly are getting where they're supposed to. Is there some other definition of "uploaded" that isn't happening?

A: 

That error happens when the browser does not send a file, but also when the filename of the sent file is interpreted by PHP as an empty string (see main/rfc1867.c).

Try to force a charset on the form, like this:

<form accept-charset="utf-8" enctype="multipart/form-data" method="post" action="dest.php">

If it doesn't work, sniff the HTTP request where the files are sent (e.g. with wireshark) and post the results. Try also another browser.

EDIT: Your browser is sending only one file. UPLOAD_ERR_NO_FILE doesn't mean "no file at all was uploaded". If $_FILES["attachments"]["error"][$n] == UPLOAD_ERR_NO_FILE it means "no file was uploaded for $n-th file input".

Content-Type: multipart/form-data; boundary=---------------------------3764294497346
Content-Length: 4113

-----------------------------3764294497346
Content-Disposition: form-data; name="subject"

Ritz Camera Club Presentation
-----------------------------3764294497346
Content-Disposition: form-data; name="meeting_date"

May 2010
-----------------------------3764294497346
Content-Disposition: form-data; name="posted_by"

esthermstrom
-----------------------------3764294497346
Content-Disposition: form-data; name="body"

sdjflksjdflsjf
-----------------------------3764294497346
Content-Disposition: form-data; name="attachments[]"; filename="Log.txt"
Content-Type: text/plain

contents of the file snipped
-----------------------------3764294497346
Content-Disposition: form-data; name="attachments[]"; filename=""
Content-Type: application/octet-stream


-----------------------------3764294497346
Content-Disposition: form-data; name="attachments[]"; filename=""
Content-Type: application/octet-stream


-----------------------------3764294497346
Content-Disposition: form-data; name="attachments[]"; filename=""
Content-Type: application/octet-stream


-----------------------------3764294497346
Content-Disposition: form-data; name="submit"

Post Writeup
-----------------------------3764294497346--
Artefacto
Thanks. I added the accept-charset, and tried it in all three major browsers (firefox, ie8, chrome). Still getting the error, in all browsers. I've never used anything like Wireshark, but just downloaded it and will see if I can figure out how to use it and post the results. I'm assuming I'd want to post the HTTP Post results?
EmmyS
@EmmyS. Yes, that's it. Post only the MIME headers if the files are big e.g.:-----------MV9ObR7y7KD9eZvr93dXZXContent-Disposition: form-data; name="attachments[]"; filename="filename.txt"Content-Type: text/plain
Artefacto
@EmmyS Maybe it's better you try it with small files and post the whole HTTP request. That way I can try to reproduce the problem.
Artefacto
All the files I'm testing with are small. I'm still trying to find the data I need in Wireshark - there's so much stuff there!
EmmyS
@EmmyS You can display only HTTP traffic. Also make sure you sniff during a short period of time.
Artefacto
Thanks, but I know nothing about traffic and packets, and Wireshark is really over my head. Here's a link to the output of the post request according to Firebug: http://www.pcbug.org/webTests/postOutput.txt
EmmyS
@EmmyS I see nothing wrong, but to test it I'd need the raw data (with all the headers and the line breaks). Wireshark is not that difficult to use...
Artefacto
@EmmyS OK I couldn't see it properly due at first to missing line breaks, but your browser is only sending one file.
Artefacto
Yes, that's correct. For my test, I did only try to upload a single file. I'm still not understanding why it's returning the error that states that NO files were uploaded.
EmmyS
Also - I just tried Wireshark again. I set it up to automatically stop the capture after 5 seconds so it wouldn't be overwhelming. Before starting the capture, I filled out all my form data, so that ideally only the submit would be captured. I turned on the capture, then hit Submit. When I went back to Wireshark, there were 44 packets, and not a single one was HTTP.
EmmyS
@EmmyS It doesn't mean "no file at all was uploaded". It means "no file was uploaded for that input".
Artefacto
OK, that makes sense. So if I have 4 possible file inputs, I need to test for an error with all of them, and only if it's 4 for one that has a filename should it actually throw the error and stop my code. Thank you, I'll give that a shot.
EmmyS
@EmmyS If your are running the httpd daemon yourself, see here: http://wiki.wireshark.org/CaptureSetup/Loopback
Artefacto
Thanks, I think that's probably what I need to do - I'm testing this on my dev box, which has Apache/PHP installed. I'm accessing the page via http://127.0.0.1.
EmmyS