How to check if a file has been selected in the input field?

Asked

Viewed 2,830 times

3

I do a form validation to ensure that the file a user uploaded is of the right type. But the upload is optional, so I want to skip the validation if it hasn’t uploaded anything and uploaded the rest of the form. How can I verify if he carried something or not in the <input name="file-upload[]" type="file" multiple="multiple" />?

My HTML form:

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

As I value in back-end to see if he loaded something or not in the input for files?

Is it with is_uploaded_file()? Or isset? Or with Empty? Or do you have to check the error code? Because even not selecting comes the empty file-upload array.

  • 2

    My question is, are you using file-upload[], really wants to send more than one file?

  • ... But upload is optional. The user may or may not submit, it is an option. Maybe he sends 1 or more, maybe he does not send anything. But the initial idea is that yes @Wallacemaxters

  • is_uploaded_file is to check if the upload was uploaded and if it is a "malicious" file, but does not need to use along with move_uploaded_file, internally the move_uploaded_file already makes the same check as the is_uploaded_file. PS: As @Wallacemaxters said, if it’s just a file use the [] is redundant.

  • I want to leave it open to upload multiple @Guilhermenascimento files. What I want to know is how do I validate in the back end to see if it loaded something or not in the input for files? If the file input had any selected or not.

  • @user97816 as I have already said in my comment, the move_uploaded_file does it alone, it checks if it is a uploaded file and checks if it is malicious (for Unix-like and/or apache environments I believe)

  • 1

    I think you’re confusing validating upload file with validating upload INPUT, which could be two different things. isset as well as Empty has the function of validating variables and defined keys?

  • @Guilhermenascimento I want to know if the user sent/selected/chose at least one file in my form. I want PHP to tell me if the user sent/selected/chose at least one file in my form, if the <input name="file-upload[]" type="file" Multiple="Multiple" /> has or does not have a selected file when it arrives in back-end. I do not want to AJAX, or validate the file type sent, but to know if any file came, if any file was selected in the input for files.

  • @user97816 has seen the answer down there ? isset checks whether a file has been uploaded, foreach checking move_uploaded_file responds to the upload result

  • I’m sorry I wasn’t clear.

  • @user97816 you want when the user sends the form, check if you have any file sent, if you have, upload and check if it was sent, if you have no file together, does nothing, is that it? tries to see if the answer I gave solves, if not solved warns to try to find the problem.

  • @That’s what anthraxisbr is :(. I’ll see the answers

  • was just what I explain in the comment, the use is Empty or isset, but has more details, I will formulate a response

  • Okay. It’s hard to get inside my head, but I’m getting it @Guilhermenascimento

Show 8 more comments

2 answers

5


The is_uploaded_file is not used for this, it is used to check if something passed came by upload, assuming that you have created a function to for example check the last modification of the file, using filemtime, but it can’t be an upload file, so you would do something like:

function my_file_mtime($input)
{
     if (is_uploaded_file($input)) {
          return false;
     }

     return filemtime($input);
}

And the case would wear so:

var_dump(my_file_mtime('foo/bar/baz.txt')); // retorna um numero, por exemplo int(10), supondo que o arquivo tenha o peso de 10 bytes

var_dump(my_file_mtime($_FILES['file-upload']['tmp_name'])); //Retorna false

I’m just saying this to explain a possible use of is_uploaded_file, who by his doubt, is not what you need.

Now getting back to the problem, what you want to do is check if the FORM input has been filled in, so isset and/or empty will suit you in this, because PHP generates variables as needed, in this case !empty() will be more practical, because in addition to checking whether the super global variable ($_FILES) it was generated, thus staying:

if (empty($_FILES['file-upload']['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['file-upload'];
    $total = count($arquivos['name']);

    for ($i = 0; $i < $total; $i++) {
        //Ação do upload para cada arquivo adicionado com "[]"
    }
}

In general this already solves much, even if the user has selected something, but there is still the error checking that is explained in this link:

Error Messages Explained

These are constants that you can use to know which error occurred while uploading the file:

  • UPLOAD_ERR_OK no error, upload was successful.

  • UPLOAD_ERR_INI_SIZE The uploaded file exceeds the limit set in the upload_max_filesize directive of php.ini.

  • UPLOAD_ERR_FORM_SIZE The file exceeds the limit set in MAX_FILE_SIZE in the HTML form.

  • UPLOAD_ERR_PARTIAL The file was partially uploaded.

  • UPLOAD_ERR_NO_FILE No file was sent.

  • UPLOAD_ERR_NO_TMP_DIR Missing temporary folder. Introduced in PHP 5.0.3.

  • UPLOAD_ERR_CANT_WRITE Failed to write the file to disk. Introduced in PHP 5.1.0.

  • UPLOAD_ERR_EXTENSION A PHP extension stopped uploading the file. PHP does not provide a way to determine which extension caused the interruption. Examining the list of extensions loaded with phpinfo() may help. Introduced in PHP 5.2.0.

Just compare these constants with $_FILES['file-upload']['error'] and in your case how you used [], should wear like this $_FILES['file-upload']['error'][$index] (the $index would be the iterator of for, is just one example, in which case it is the same thing as $i I used in the example above)

A simple example would be to check only if it is different from UPLOAD_ERR_OK, thus:

if (empty($_FILES['file-upload']['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['file-upload'];
    $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>';
        }
    }
}

You can also enter the detailed error message to the user:

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';
    }
}

if (empty($_FILES['file-upload']['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['file-upload'];
    $total = count($arquivos);

    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>';
        }
    }
}

2

1 - You will not carry with the form, the form will just force the upload to some script server-side (PHP) to do the upload, in case, you would receive on PHP and would do it would put the file somewhere with move_uploaded_file() (there are other possibilities¹):

Example taken from official documentation:

$uploaddir = '/pasta/para/upload';
$uploadfile = $uploaddir . basename($_FILES['file-upload']['name']);


if (move_uploaded_file($_FILES['fil-eupload']['tmp_name'], $uploadfile)) {
    echo "Se o arquivo pode ser movido para a pasta informada essa será a resposta.\n";
} else {
    echo "Caso o arquivo não tenha sido carregado para a pasta informada esta a resposta!\n";
}

Now, how do you own [] in file-upload, means you want to send more than one file, follow example adapted from the previous example:

//Diretório para upload
$uploaddir = '/pasta/para/upload';
//Salva os arquivos enviados em uma váriavel $files
$files = $_FILES['file-upload'];

//Inicia um contador (apenas para dizer em qual linha foram as respostas)
$a = 0;
//Verificando se existe algum alguma coisa em $files
if (isset($files)) {

    $name = $files['name'];
    $tmp_name = $files['tmp_name'];
    //Passando um loop por $files
    foreach ($name as $file) {
        //Definindo um diretório para o arquivo ser carregado
        $uploadfile = $uploaddir . basename($name[$a]);
        //Verificando se o arquivo pode ser carregado
        if (move_uploaded_file($tmp_name[$a], $uploadfile)) {
            echo "O arquivo $a foi carregado<br>";
        } else {
            echo "O arquivo $a não foi carregado";
        }
        //Somando ao contador
        $a += 1;
    }
} else {
    echo 'Nenhum arquivo foi enviado';
}

¹ - Upload possibilities:

is_uploaded_file

move_uploaded_file

ftp_put - Requires open FTP connection.

  • 1

    I think it would be appropriate to put an if(isset($_FILES['file-upload'])) just to ensure that the index exists, since it is not required!

  • 1

    I hadn’t thought about it, I’ll update the answer.

  • 1

    Missing a parenthesis at isset @Anthraxisbr

Browser other questions tagged

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