hasan
hasan

Reputation: 65

Multiple files uploading in multidimensional array

I have a php form with unknown number of rows where user can upload files. For this purpose I use two dimensional array.

<form action="upload_file_module.php" method="post" enctype="multipart/form-data">
<? $i = 0; ?>
<table>
    <tr>
        <td>
            <input type="hidden" name="row[<? echo $i; ?>][row_name]" value = "one"/> One
        </td>
        <td>
            <input type="file" name="row[<? echo $i; ?>][fileToUpload]" >
        </td>
        <? 
            $i++;
        ?>
    </tr>

    <tr>
        <td>
            <input type="hidden" name="row[<? echo $i; ?>][row_name]" value = "two"/> Two
        </td>
        <td>
            <input type="file" name="row[<? echo $i; ?>][fileToUpload]" >
        </td>
        <? 
            $i++;
        ?>
    </tr>
</table>    

<input type="submit" value="Upload" name="submit">

All files should be saved in different folders.

<?php
$unique_id = "folder";
$unique_id = $unique_id . '/';
foreach ( $_POST['row'] as $val )   {

    $target_dir = $unique_id;
    $target_dir = $target_dir . "/" . $val. "/";
    if (!file_exists($target_dir)) {
        mkdir($target_dir, 0777, true);
    }

    echo '<table>';
    echo '<tr>';
    echo '<td>', $val['row_name'], '</td>';
    echo '<td>', $val['fileToUpload'], '</td>';
    echo '</tr>';
    echo '</table>';

    $target_file = $target_dir . basename($_FILES[$val['fileToUpload']]["name"]);
    $uploadOk = 1;
    $imageFileType = pathinfo($target_file,PATHINFO_EXTENSION);
    // Check if image file is a actual image or fake image

    // Check if file already exists
    if (file_exists($target_file)) {
        echo "Sorry, file already exists.";
        $uploadOk = 0;
    }
    // Check file size
    if ($_FILES["fileToUpload"]["size"] > 900000000) {
        echo "Sorry, your file is too large.";
        $uploadOk = 0;
    }

    // Check if $uploadOk is set to 0 by an error
    if ($uploadOk == 0) {
        echo "Sorry, your file was not uploaded.";
    // if everything is ok, try to upload file
    } else {
        if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
            echo "The file ". basename( $_FILES["fileToUpload"]["name"]). " has been uploaded.<br>";
        } else {
            echo "Sorry, there was an error uploading your file.<br>";
        }
    }      
}

But in fact it doesn't see any files, and output looks like:

one

Sorry, file already exists.Sorry, your file was not uploaded.

two

Sorry, file already exists.Sorry, your file was not uploaded.

Upvotes: 2

Views: 2030

Answers (1)

al&#39;ein
al&#39;ein

Reputation: 1727

There were some changes to be made, in addition to the ones in the comments. Major issues are:

  1. You were trying to get both files and post data into one single array, when both $_POST and $_FILES are, in PHP nature, totally separated entities. So you're ending up trying to access a single array row when there is actually two row arrays inside both these superglobals.
  2. Your $target_file was never declared, and your $target_dir has too many slashes.
  3. The item 1 made you access $val the wrong way.

These are the final corrections I came up with, keeping the logic for your own environment. The explanation to each part is commented inside the code.

HTML form

<!DOCTYPE html>
<html>
<head></head>
<body>
	<form action="upload.php" method="post" enctype="multipart/form-data">
            <table>
	<?php $counter = 2; // number of fields you want to be printed
	for($i = 0; $i < $counter; $i++): // do proper counting ?>
                <tr>
			<td>
				<input type="hidden" name="row[]" value="<?php echo $i; ?>"/> File:
			</td>
			<td>
				<input type="file" name="row[]" >
			</td>
		</tr>
	<?php endfor; ?>
	    </table>
	    <input type="submit" value="Upload" name="submit">
	</form>
</body>
</html>

PHP Post Script

<?php
    $unique_id = "upload"; // just changed to reproduce
    $unique_id = $unique_id . '/';
    foreach ($_POST['row'] as $val)   {

        $target_dir = $unique_id;
        $target_file = $_FILES['row']['name'][$val]; //actually defining this var
        $target_dir = $target_dir . $val. "/"; // no need to index assoc nor '/'
        if (!file_exists($target_dir)) {
            mkdir($target_dir, 0777, true);
        }

        $imageFileType = pathinfo($target_dir,PATHINFO_EXTENSION);
        // Check if image file is a actual image or fake image

        // Check if file already exists
        if (file_exists($target_file)) {
            die("Sorry, file already exists."); // die if error
        }
        // Check file size
        if ($_FILES['row']['size'][$val] > 900000000) { // using the proper index reference for file
            die("Sorry, your file is too large."); //die if error
        }

        // Check if there are error msg in $_FILES
        if ($_FILES['row']['error'][$val] != 0) {
            die("Sorry, your file was not uploaded."); // die if error
            // if everything is ok, try to upload file
        } else {
            // point your move_files with the final name of the actual file to be moved
            if (move_uploaded_file($_FILES['row']['tmp_name'][$val], $target_dir.'/'.$_FILES['row']['name'][$val])) {
                echo "The file ". basename($_FILES['row']['name'][$val]). " has been uploaded.<br>";
            } else {
                die("Sorry, there was an error uploading your file.");
            }
        }
    }

Final Output (after uploading two dummy files)

Array
(
    [row] => Array
        (
            [0] => 0
            [1] => 1
        )

    [submit] => Upload
)
Array
(
    [row] => Array
        (
            [name] => Array
                (
                    [0] => dummyfile1.docx
                    [1] => dummyfile2.mpp
                )

            [type] => Array
                (
                    [0] => application/vnd.openxmlformats-officedocument.wordprocessingml.document
                    [1] => application/vnd.ms-project
                )

            [tmp_name] => Array
                (
                    [0] => C:\Windows\Temp\php73DA.tmp
                    [1] => C:\Windows\Temp\php73DB.tmp
                )

            [error] => Array
                (
                    [0] => 0
                    [1] => 0
                )

            [size] => Array
                (
                    [0] => 0
                    [1] => 180224
                )

        )

)
The file dummyfile1.docx has been uploaded.
The file dummyfile2.mpp has been uploaded.

Upvotes: 1

Related Questions