Upload Images: More than one input file with the same name

Asked

Viewed 647 times

0

I need to upload images, but I can’t create just one input and use the Multiple, like this:

<input type="file" name="images[]" multiple>

What I need is to create 5 inputs that in the backend produce the same result as above.

I tried to create two inputs with the same name, but it didn’t work:

<input type="file" name="images[]">
<input type="file" name="images[]">

PS: It has to be this way, because it is easier for the user to manipulate one at a time.

PHP code:

foreach(Input::file('images') as $imagem){
    $destinationPath = 'uploads/' . Auth::user()->loja_id . '/produtos';
    $extension = $imagem->getClientOriginalExtension();
    $fileName = date('YmdHis')
              .microtime(true)
              .rand(111111111, 999999999)
              .'.'
              .$extension;

    $upload_success = $imagem->move($destinationPath, $fileName);
    $image = new ProdutoImagem;
    $image->produto_id = $produto->id;
    $image->imagem = $fileName;
    $image->save();
}

AJAX code.

$(document).on('submit', '#form-produto', function(e){
                    e.preventDefault();

                    $.ajax({
                        type: 'POST',
                        url: $(this).attr('action'),
                        data: new FormData(this),
                        dataType: 'json',
                        contentType: false,
                        cache: false,
                        processData:false,
                        success: function (data){
                            if(data.status == true){
                                window.location = '/admin/' + data.url;
                            }

                            else{
                                $('.alert span').remove();
                                $('.alert').show();
                                $('.alert').append('<span>' + data.msg + '</span>');
                            }
                        }
                    });
                });
  • What was the result of var_dump($_FILES)?

  • array(1) { ["images"]=> array(5) { ["name"]=> array(2) { [0]=> string(50) "10888874_794541107285499_31691180108787459_n.jpg" [1]=> string(17) "3geYt-profile.jpg" } ["type"]=> array(2) { [0]=> string(10) "image/jpeg" [1]=> string(10) "image/jpeg" } ["tmp_name"]=> array(2) { [0]=> string(24) "C: xampp tmp php761A.tmp" [1]=> string(24) "C: xampp tmp php761B.tmp" } ["error"]=> array(2) { [0]=> int(0) [1]=> int(0) } ["size"]=> (2 array) { [0]=> int(51554) [1]=> int(49193) } } }

  • If 2 images were selected, it seems to be correct. What is the problem?

  • Now I put only two images to test. Of the error in the time to go through the foreach to register them.

  • Then it must be the foreach that is wrong. See William’s answer...

1 answer

3


The answer contains example with PHP and with Laravel because the author did not inform that he used Windows in the first version

As in the doc http://php.net/manual/en/features.file-upload.multiple.php the use should be like this:

  1. to the first file $_FILES['imagem']['tmp_name'][0]
  2. Second file $_FILES['imagem']['tmp_name'][1]

And so on, that is to increase the number of each file, you can use the for () that will solve everything.

An example:

if (empty($_FILES['imagem']['name'])) {
    echo 'Você não selecionou nenhum arquivo';//Aqui você pode trocar por um alert ou customizar como desejar, é um aviso que o usuário provavelmente não selecionou nada
} else {
    $arquivos = $_FILES['imagem'];
    $total = count($arquivos['name']);

    for ($i = 0; $i < $total; $i++) {
        $nome = $arquivos['name'][$i];

        if ($arquivos['error'][$i] !== UPLOAD_ERR_OK) {
            echo 'Erro ao fazer upload de ', htmlspecialchars($nome), '<br>';
            continue;
        }

        if (move_uploaded_file($arquivos['tmp_name'][$i], 'pasta/foo/bar/' . $nome)) {
            echo 'O arquivo ', htmlspecialchars($nome),' foi carregado<br>';
        } else {
            echo 'O arquivo ', htmlspecialchars($nome),' não foi carregado<br>';
        }
    }
}

Extras

It is important to remember that the form should contain enctype="multipart/form-data", for example:

<form enctype="multipart/form-data" action="upload.php" method="POST">

Here’s an example of how to check for other errors that might occur in the upload /a/256888/3635:

function mensagem_de_erro($code) {
    switch ($code) {
        case UPLOAD_ERR_OK: //Se o upload for OK ele retorna false
            return false;
        case UPLOAD_ERR_INI_SIZE:
            return 'O upload excedeu o limite máximo definido no upload_max_filesize no php.ini';
        case UPLOAD_ERR_FORM_SIZE:
            return 'O upload excedeu o MAX_FILE_SIZE especificado no formulário HTML';
        case UPLOAD_ERR_PARTIAL:
            return 'O upload foi parcial';
        case UPLOAD_ERR_NO_FILE:
            return 'Não foi selecionado um arquivo';
        case UPLOAD_ERR_NO_TMP_DIR:
            return 'A pasta temporária não foi definida (php.ini) ou não é acessivel';
        case UPLOAD_ERR_CANT_WRITE:
            return 'Não pode fazer o upload na pasta temporaria';
        case UPLOAD_ERR_EXTENSION:
            return 'O upload foi interrompido por uma extensão PHP';
        default:
            return 'Erro desconhecido';
    }
}

The use must be something like that:

for ($i = 0; $i < $total; $i++) {
    $nome = $arquivos['name'][$i];

    $erro = mensagem_de_erro($arquivos['error'][$i]);

    if ($erro) {
        echo $erro, ' - arquivo: ', htmlspecialchars($nome), '<br>';
        continue; //Pula o item atual do array para o proximo se algo falha no atual
    }

    if (move_uploaded_file($arquivos['tmp_name'][$i], 'pasta/foo/bar/' . $nome)) {
        echo 'O arquivo ', htmlspecialchars($nome),' foi carregado<br>';
    } else {
        echo 'O arquivo ', htmlspecialchars($nome),' não foi carregado<br>';
    }
}

If it’s Laravel

If it’s Laravel 5.2:

public function metodoDoController(Request $request) {

    if($request->hasFile('attachment')) {

       $files = $request->file('imagem');

        foreach ($files as $file) {
            $file->move('foo/bar/pasta');
        }
    }

}

If Laravel 5.3+ use like this:

public function metodoDoController(Request $request) {

    if($request->hasFile('attachment')) {

        $files = $request->file('imagem');

        foreach ($files as $file) {
            $file->store('foo/bar/pasta');
        }
    }

}

More details on https://laravel.com/docs/5.5/requests#files

  • I forgot to mention in the post that I am using Laravel syntax to upload. And it uses the following: Input::file('images'). I already edited the post with php code.

  • @Diegovieira qual version of Laravel?

  • 5.2. This code only works with an input with the Multiple properties. But not like this.

  • @Diegovieira edited the answer

  • I’m doing this, only this form of error when I use two inputs file with the same name. However if I use only one with the Multiple property, it works normal.

  • @Diegovieira what error? My code looks very different from yours in the question, try to redo and observe everything.

  • Now that I went to see, the problem is ajax. I sent the form directly to the controller, without going through ajax and it worked normal.

  • Strange that ajax works normal the other way using Multiple

  • 2

    Poh, but you never said you were using Ajax, so you make everything difficult, I spent the most time answering and the problem was totally something else :(

  • It is that I never imagined that it was ajax giving problem, since it worked before. I put the code in the post. I’m also using the jquery mobile library.

  • 1

    But that’s why if you will ask you have to give details, help us to help you. Follow the MCVE: https://answall.com/help/mcve

  • Solved the problem, I removed the cache attribute: false from ajax.

  • @Diegovieira ah, I get it, but it’s strange the cache: false should only work when it’s GET, for POST the cache doesn’t even exist, so false or true would be the same thing... Let me know what version of jQuery you used.

  • Dude, it worked once, but when I uploaded it again, it was a problem. Jquery 1.11.1 and Jquery Mobile 1.4.5

  • @Diegovieira Jquery 1.11.1 is old already, probably was an old BUG of this version and has already been fixed in the new ones, but do not worry, cache: false with POST is redundant, either in any version, or need not use.

  • The problem is that jquery mobile does not work in the latest versions of jquery.

Show 11 more comments

Browser other questions tagged

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