How to transform this code to validate multiple files?

Asked

Viewed 65 times

0

The code below is found in PHP documentation, allows you to upload files, only it only allows one file per upload. How to transform this code to validate multiple files?

<?php

header('Content-Type: text/plain; charset=utf-8');

try {

    // Undefined | Multiple Files | $_FILES Corruption Attack
    // If this request falls under any of them, treat it invalid.
    if (
        !isset($_FILES['upfile']['error']) ||
        is_array($_FILES['upfile']['error'])
    ) {
        throw new RuntimeException('Invalid parameters.');
    }

    // Check $_FILES['upfile']['error'] value.
    switch ($_FILES['upfile']['error']) {
        case UPLOAD_ERR_OK:
            break;
        case UPLOAD_ERR_NO_FILE:
            throw new RuntimeException('No file sent.');
        case UPLOAD_ERR_INI_SIZE:
        case UPLOAD_ERR_FORM_SIZE:
            throw new RuntimeException('Exceeded filesize limit.');
        default:
            throw new RuntimeException('Unknown errors.');
    }

    // You should also check filesize here. 
    if ($_FILES['upfile']['size'] > 1000000) {
        throw new RuntimeException('Exceeded filesize limit.');
    }

    // DO NOT TRUST $_FILES['upfile']['mime'] VALUE !!
    // Check MIME Type by yourself.
    $finfo = new finfo(FILEINFO_MIME_TYPE);
    if (false === $ext = array_search(
        $finfo->file($_FILES['upfile']['tmp_name']),
        array(
            'jpg' => 'image/jpeg',
            'png' => 'image/png',
            'gif' => 'image/gif',
        ),
        true
    )) {
        throw new RuntimeException('Invalid file format.');
    }

    // You should name it uniquely.
    // DO NOT USE $_FILES['upfile']['name'] WITHOUT ANY VALIDATION !!
    // On this example, obtain safe unique name from its binary data.
    if (!move_uploaded_file(
        $_FILES['upfile']['tmp_name'],
        sprintf('./uploads/%s.%s',
            sha1_file($_FILES['upfile']['tmp_name']),
            $ext
        )
    )) {
        throw new RuntimeException('Failed to move uploaded file.');
    }

    echo 'File is uploaded successfully.';

} catch (RuntimeException $e) {

    echo $e->getMessage();

}

?>

1 answer

-1

First you have to make sure that the fields FILE form be "Array":

<form action="file-upload.php" method="post" enctype="multipart/form-data">
  Envie esses arquivos:<br />
  <input name="upfile[]" type="file" /><br />
  <input name="upfile[]" type="file" /><br />
  <input type="submit" value="Enviar arquivos" />
</form>

When the form above is submitted, the arrays $_FILES['upfile'], $_FILES['upfile']['name'], and $_FILES['upfile']['size'] will be placed in an array $_FILES:

Array
(
    [name] => Array
        (
            [0] => foo.txt
            [1] => bar.txt
        )

    [type] => Array
        (
            [0] => text/plain
            [1] => text/plain
        )

    [tmp_name] => Array
        (
            [0] => /tmp/phpYzdqkD
            [1] => /tmp/phpeEwEWG
        )

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

    [size] => Array
        (
            [0] => 123
            [1] => 456
        )
)

in the code you will have to put a for to go through it and make the respective uploads:

<?php

header('Content-Type: text/plain; charset=utf-8');

for($i = 0; $i < count($_FILES['upfile']['name']); $i++){

try {

    // Undefined | Multiple Files | $_FILES Corruption Attack
    // If this request falls under any of them, treat it invalid.
    if (
        !isset($_FILES['upfile']['error'][$i]) ||
        is_array($_FILES['upfile']['error'][$i])
    ) {
        throw new RuntimeException('Invalid parameters.');
    }

    // Check $_FILES['upfile']['error'] value.
    switch ($_FILES['upfile']['error'][$i]) {
        case UPLOAD_ERR_OK:
            break;
        case UPLOAD_ERR_NO_FILE:
            throw new RuntimeException('No file sent.');
        case UPLOAD_ERR_INI_SIZE:
        case UPLOAD_ERR_FORM_SIZE:
            throw new RuntimeException('Exceeded filesize limit.');
        default:
            throw new RuntimeException('Unknown errors.');
    }

    // You should also check filesize here. 
    if ($_FILES['upfile']['size'][$i] > 1000000) {
        throw new RuntimeException('Exceeded filesize limit.');
    }

    // DO NOT TRUST $_FILES['upfile']['mime'][$i] VALUE !!
    // Check MIME Type by yourself.
    $finfo = new finfo(FILEINFO_MIME_TYPE);
    if (false === $ext = array_search(
        $finfo->file($_FILES['upfile']['tmp_name'][$i]),
        array(
            'jpg' => 'image/jpeg',
            'png' => 'image/png',
            'gif' => 'image/gif',
        ),
        true
    )) {
        throw new RuntimeException('Invalid file format.');
    }

    // You should name it uniquely.
    // DO NOT USE $_FILES['upfile']['name'] WITHOUT ANY VALIDATION !!
    // On this example, obtain safe unique name from its binary data.
    if (!move_uploaded_file(
        $_FILES['upfile']['tmp_name'][$i],
        sprintf('./uploads/%s.%s',
            sha1_file($_FILES['upfile']['tmp_name'][$i]),
            $ext
        )
    )) {
        throw new RuntimeException('Failed to move uploaded file.');
    }

    echo 'File is uploaded successfully.';

} catch (RuntimeException $e) {

    echo $e->getMessage();

}

}

?>
  • 1

    1º: There is an error on line 5, missing the ; on the condition. 2°: You upload it for $_POST, while it should go through $_FILES.

  • Tidy vlw....

  • No fix. It’s $_FILES. Missed the S.

  • 1

    No one here was stupid, you said you did, while actually you were still wrong, you were missing the S. Either you’re 100% right, or you’re wrong.

  • 2

    Guilherme, Stormwind just made a note, he is helping you, be respectful, follow our model https://answall.com/help/be-nice, in no time the Storwind offended or depreciated something, he merely pointed out your faults that can be corrected to thus improve the response.

  • @Guilhermenascimento education fits here and everywhere the initial note was respectful and I treated him well, but because I forgot an S the guy come to talk that I did not tidy... haaa pf.... it cost nothing to be polite, just as he I mistake too.

  • 2

    I have not seen at any time lack of education, he just gave emphasis to help you fix problems in your code, it is up to you not to take person side and understand as a constructive criticism, no need for exaggerations.

  • @Guilhermebiancardi, Stormwind’s appointment was right and coherent. As much as, humanly, the error was 1 character out of 1000 (hence error of 0.1%), the compiler/interpreter of the code will not generate the expected result. Imagine you wrote an entire class in Java and forgot one ;: your code will be wrong. Or else in Python you mix in the same indentation block 2 spaces and 3 spaces. The implementation is wrong.

Show 3 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.