Resumo : neste tutorial, você aprenderá como fazer upload de vários arquivos para o servidor em PHP com segurança.
Introdução ao PHP fazer upload de vários arquivos
No tutorial anterior, você aprendeu como fazer upload de um único arquivo de um cliente para o servidor web em PHP . Todas as regras de upload de um único arquivo são relevantes para vários arquivos.
Primeiro, o elemento do formulário HTML deve ter os enctype
atributos definidos para "multipart/form-data"
permitir o upload de arquivos. Por exemplo:
<form action="index.php" method="post" enctype="multipart/form-data">
Linguagem de código: PHP ( php )
Segundo, o elemento de entrada do arquivo deve ter o multiple
atributo e seu nome deve ter colchetes ( []
) assim:
<input type="file" name="files[]" id="files" multiple />
Linguagem de código: PHP ( php )
Em PHP, você pode acessar $_FILES['files']
para obter as informações dos arquivos enviados:
<?php
var_dump($_FILES['files']);
Linguagem de código: HTML, XML ( xml )
O 'files'
é o nome do elemento de entrada do arquivo.
Exemplo de upload de vários arquivos em PHP
O exemplo a seguir reutiliza as funções e lógicas existentes desenvolvidas no tutorial de upload de arquivo .
Primeiro, crie a seguinte estrutura de projeto:
├── inc
| ├── flash.php
| └── functions.php
├── index.php
├── upload.php
└── uploads
Em segundo lugar, adicione o seguinte código para index.php
criar o formulário de upload de arquivo:
<?php
session_start();
require_once __DIR__ . '/inc/flash.php';
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>PHP upload multiple files</title>
<link rel="stylesheet" href="https://tutorials.acervolima.com/app/css/style.css" />
</head>
<body>
<?php flash('upload') ?>
<main>
<form action="upload.php" method="post" enctype="multipart/form-data">
<div>
<label for="files">Select files to upload:</label>
<input type="file" name="files[]" id="files" multiple required/>
</div>
<div>
<button type="submit">Upload</button>
</div>
</form>
</main>
</body>
</html>
Linguagem de código: HTML, XML ( xml )
O index.php
faz o seguinte:
1) Inicie uma nova sessão ou retome uma sessão existente:
session_start();
2) Carregue o código do inc/flash.php
arquivo:
require_once __DIR__ . '/inc/flash.php';
Linguagem de código: PHP ( php )
3) Chame a flash()
função para mostrar uma mensagem com o nome 'upload'
. A flash()
função está definida no flash.php
arquivo.
<?php flash('upload') ?>
Linguagem de código: HTML, XML ( xml )
4) Crie um formulário de upload que envie para o upload.php
arquivo.
Terceiro, adicione o seguinte código ao upload.php
arquivo para validar e fazer upload de vários arquivos:
<?php
session_start();
require_once __DIR__ . '/inc/flash.php';
require_once __DIR__ . '/inc/functions.php';
const ALLOWED_FILES = [
'image/png' => 'png',
'image/jpeg' => 'jpg'
];
const MAX_SIZE = 5 * 1024 * 1024; // 5MB
const UPLOAD_DIR = __DIR__ . '/uploads';
$is_post_request = strtolower($_SERVER['REQUEST_METHOD']) === 'post';
$has_files = isset($_FILES['files']);
if (!$is_post_request || !$has_files) {
redirect_with_message('Invalid file upload operation', FLASH_ERROR);
}
$files = $_FILES['files'];
$file_count = count($files['name']);
// validation
$errors = [];
for ($i = 0; $i < $file_count; $i++) {
// get the uploaded file info
$status = $files['error'][$i];
$filename = $files['name'][$i];
$tmp = $files['tmp_name'][$i];
// an error occurs
if ($status !== UPLOAD_ERR_OK) {
$errors[$filename] = MESSAGES[$status];
continue;
}
// validate the file size
$filesize = filesize($tmp);
if ($filesize > MAX_SIZE) {
// construct an error message
$message = sprintf("The file %s is %s which is greater than the allowed size %s",
$filename,
format_filesize($filesize),
format_filesize(MAX_SIZE));
$errors[$filesize] = $message;
continue;
}
// validate the file type
if (!in_array(get_mime_type($tmp), array_keys(ALLOWED_FILES))) {
$errors[$filename] = "The file $filename is allowed to upload";
}
}
if ($errors) {
redirect_with_message(format_messages('The following errors occurred:',$errors), FLASH_ERROR);
}
// move the files
for($i = 0; $i < $file_count; $i++) {
$filename = $files['name'][$i];
$tmp = $files['tmp_name'][$i];
$mime_type = get_mime_type($tmp);
// set the filename as the basename + extension
$uploaded_file = pathinfo($filename, PATHINFO_FILENAME) . '.' . ALLOWED_FILES[$mime_type];
// new filepath
$filepath = UPLOAD_DIR . '/' . $uploaded_file;
// move the file to the upload dir
$success = move_uploaded_file($tmp, $filepath);
if(!$success) {
$errors[$filename] = "The file $filename was failed to move.";
}
}
$errors ?
redirect_with_message(format_messages('The following errors occurred:',$errors), FLASH_ERROR) :
redirect_with_message('All the files were uploaded successfully.', FLASH_SUCCESS);
Linguagem de código: HTML, XML ( xml )
Como upload.php
funciona:
1) Inicie uma nova sessão ou retome uma já existente:
session_start();
2) Carregue o código de flash.php
e functions.php
:
require_once __DIR__ . '/inc/flash.php';
require_once __DIR__ . '/inc/functions.php';
Linguagem de código: PHP ( php )
Observe que você deve usar o tutorial flash.php
da mensagem flash e functions.php
do tutorial de upload de arquivo .
Como se upload.php
trata de vários arquivos, ele emitirá várias mensagens de erro, uma para cada arquivo carregado.
Para tornar isso conveniente, podemos definir uma função que retorne uma única mensagem de erro a partir de várias mensagens de erro como esta:
function format_messages(string $title, array $messages): string
{
$message = "<p>$title</p>";
$message .= '<ul>';
foreach ($messages as $key => $value) {
$message .= "<li>$value</li>";
}
$message .= '<ul>';
return $message;
}
Linguagem de código: PHP ( php )
E adicione esta format_messages()
função ao functions.php
arquivo.
3) Retorne uma mensagem de erro se o método de solicitação não for POST
ou $_FILES
não contiver o files
campo:
$is_post_request = strtolower($_SERVER['REQUEST_METHOD']) === 'post';
$has_files = isset($_FILES['files']);
if (!$is_post_request || !$has_files) {
redirect_with_message('Invalid file upload operation', FLASH_ERROR);
}
Linguagem de código: PHP ( php )
4) Obtenha os arquivos enviados $_FILES
e o número de arquivos enviados:
$files = $_FILES['files'];
$file_count = count($files['name']);
Linguagem de código: PHP ( php )
5) Para cada arquivo carregado, verifique o código de erro e valide o tamanho e tipo do arquivo. Se ocorrer um erro, adicione uma mensagem de erro ao $errors
array, ignore o loop de validação atual e valide o próximo arquivo.
// validation
$errors = [];
for ($i = 0; $i < $file_count; $i++) {
// get the uploaded file info
$status = $files['error'][$i];
$filename = $files['name'][$i];
$tmp = $files['tmp_name'][$i];
// an error occurs
if ($status !== UPLOAD_ERR_OK) {
$errors[$filename] = MESSAGES[$status];
continue;
}
// validate the file size
$filesize = filesize($tmp);
if ($filesize > MAX_SIZE) {
// construct an error message
$message = sprintf("The file %s is %s which is greater than the allowed size %s",
$filename,
format_filesize($filesize),
format_filesize(MAX_SIZE));
$errors[$filesize] = $message;
continue;
}
// validate the file type
if (!in_array(get_mime_type($tmp), array_keys(ALLOWED_FILES))) {
$errors[$filename] = "The file $filename is allowed to upload";
}
}
Linguagem de código: PHP ( php )
Se ocorreu um erro, redirecione de volta para index.php
e mostre a mensagem de erro:
if ($errors) {
redirect_with_message(format_messages('The following errors occurred:',$errors), FLASH_ERROR);
}
Linguagem de código: PHP ( php )
Observe que usamos a format_messages()
função para converter o $errors
array em uma única mensagem de erro formatada.
6) Se nenhum erro ocorrer, mova cada arquivo para o diretório de upload:
// move the files
for($i = 0; $i < $file_count; $i++) {
$filename = $files['name'][$i];
$tmp = $files['tmp_name'][$i];
$mime_type = get_mime_type($tmp);
// set the filename as the basename + extension
$uploaded_file = pathinfo($filename, PATHINFO_FILENAME) . '.' . ALLOWED_FILES[$mime_type];
// new filepath
$filepath = UPLOAD_DIR . '/' . $uploaded_file;
// move the file to the upload dir
$success = move_uploaded_file($tmp, $filepath);
if(!$success) {
$errors[$filename] = "The file $filename was failed to move.";
}
}
Linguagem de código: PHP ( php )
8) Mostrar a mensagem de erro se a movimentação apresentar erro. Caso contrário, mostre uma mensagem de sucesso:
$errors ?
redirect_with_message(format_messages('The following errors occurred:',$errors), FLASH_ERROR) :
redirect_with_message('All the files were uploaded successfully.', FLASH_SUCCESS);
Linguagem de código: PHP ( php )
Resumo
- Defina
enctype
o atributo do formulário como"multipart/form-data"
para permitir o upload de arquivos no formulário. - Defina o
multiple
atributo e adicione colchetes ([]
) ao elemento de entrada do arquivo para fazer upload de vários arquivos. - Sempre valide as informações
$_FILES
antes de processá-las. - Use a
move_uploaded_file()
função para mover os arquivos de upload.