tags:

views:

110

answers:

4

There may be a better way of doing this and I'm certainly open to suggestions.

I have a file upload script that will handle multiple uploads. What I want to do is count the number of iterations that the loop makes for each file that was successfully moved and if that number equals the total number of files uploaded, then use an exception to show the user that the files were received.

I thought that I would increment inside the loop then count from there but what I am getting is an array for each file that is uploaded which results in an incorrect total. Is there a better way to do this or successfully count each iteration?

This is the structure I have to work with

    foreach($files as $file)
    {
        if ($file['error'] == UPLOAD_ERR_OK)
        {
            move_uploaded_file($file['tmp_name'], $filename);
        }
        else
        {
           //error
        }
    }
A: 

foreach ($array as &$item)

You can just do count($array)

Paul Creasey
Thanks Paul but as I stated above, that does not produce the correct results. I get an array for every file that was uploaded. If it were a single array it would work. I just can't seem to get the array correct.
Timmay
That's what we call a multidimensional or nested array. So for every file that's uploaded, you get another array inside the $_FILES array. Every single array in $_FILES contains information about a specific file. And you *can* count($_FILES), no problem there.
Niels Bom
Yes, I'm very familiar with multi-dimensional arrays. With the default structure of the $_FILES array, when uploading multiple files, this is not possible without first rearranging that array.
Timmay
I'll show a code example in an answer.
Niels Bom
Thanks Niels. I appreciate it.
Timmay
A: 

Just throwing this out there since you know the number of files how but just using a for loop. with two counters one for the loop and one for successes, and unless your script fails mostly ( and you want to not how unusual it is that everything worked) don't throw an exception if everything works.

rerun
hmm.. That makes sense. How would I use two counters tho?
Timmay
+3  A: 

You pretty much have to do it with a counter.

$success = 0;
foreach($_FILES as $file) {

    if(is_uploaded_file($file['tmp_name'])) {
        move_uploaded_file($file['tmp_name'], $destination);
        $success += 1;
    }
}

if($success != count($_FILES)) {
    //error message / exception
}

Edit - You can set an error flag, or flags in your error handling... but there's not really a way to do this that is insanely better.

foreach($files as $file)
{
    if ($file['error'] == UPLOAD_ERR_OK)
    {
        move_uploaded_file($file['tmp_name'], $filename);
    }
    else
    {
       //error
       $upload_errors += 1;
       //or, to get a little more info...
       //$upload_errors[] = $file
    }
}

if( $upload_errors == 0) { //or count($upload_errors) == 0
    // tell the user that the upload failed.
}
davethegr8
Thanks Dave. I've already attempted to use a counter but I am checking for $_FILES['error'] first. If there is an error, then I throw an exception. I'll post some code above in a minute. Please have a look.
Timmay
I don't think there's any vastly better way to do this. Of course, if there is I want to see it.
davethegr8
Thanks Dave. Using your example, would this preclude me from using exceptions in the else block?
Timmay
Dave, outside the foreach loop I am simply returning a success message and that works. It's certainly not optimal because I was hoping to echo back to the user, the files that were successfully uploaded. This was why I wanted to do this inside the loop where I had access to the filenames.
Timmay
@Timmay - Oh, I see. Why not add a message to the session variable? example: `$_SESSION['file_error'] = '(Your message here)';` and then in your view, `echo $_SESSION['file_error'];` That's a pretty standardized method.
davethegr8
A: 

Here you can see that you can use count($_FILES) to count the number of uploaded files. Mind you, this is not the number of correctly uploaded files.

<?php
if (isset($_FILES) && !empty($_FILES)) {
    echo count($_FILES).' files were uploaded<br>';
    ?><pre><?php
    print_r($_FILES);
    ?></pre><?php

}
?>
<form 
    action="<?php echo $_SERVER['PHP_SELF'];?>" 
    method="post"
    enctype="multipart/form-data"
>
    File 1<input type="file" name="file1"><br>
    File 2<input type="file" name="file2"><br>
    File 3<input type="file" name="file3"><br>
    <input type="submit" value="upload">
</form>
Niels Bom
Niels, thanks for the example. What I am getting when I upload two files is a count of "2" 2x. In other words, a "2" for each iteration. Isn't there a way to have it only count a single time?
Timmay
Sorry, I just don't understand you, can you give a code example?Or, leave it be, I see you've already flagged an answer as correct.
Niels Bom