Formulário de Upload em HTML
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<title>Envio de Arquivo</title>
</head>
<body>
<h1>Escolha um arquivo para enviar</h1>
<form action="processar_envio.php" method="post" enctype="multipart/form-data">
<label for="arquivo">Arquivo:</label>
<input type="file" name="arquivo" id="arquivo">
<input type="submit" value="Enviar">
</form>
</body>
</html>
Função PHP para Upload com Validações
A função aprimorada abaixo inclui verificações de segurança essenicais para uso em produção, como limitação de tamanho, validação de extensões e tipos MIME, geração de nomes de arquivo seguros e tratamenot básico de imagens.
<?php
function processarUpload($campoArquivo, $diretorioDestino, $extensoesPermitidas = [], $tamanhoMaximo = 0, $tiposMimePermitidos = []) {
// Verifica se a requisição é do tipo POST e se o arquivo foi enviado
if ($_SERVER['REQUEST_METHOD'] !== 'POST' || !isset($_FILES[$campoArquivo])) {
return ['sucesso' => false, 'mensagem' => 'Requisição inválida.'];
}
$arquivoEnviado = $_FILES[$campoArquivo];
// Trata erros comuns no upload
if ($arquivoEnviado['error'] !== UPLOAD_ERR_OK) {
$mensagensErro = [
UPLOAD_ERR_INI_SIZE => 'O arquivo excede o limite definido no servidor.',
UPLOAD_ERR_FORM_SIZE => 'O arquivo excede o limite permitido pelo formulário.',
UPLOAD_ERR_NO_FILE => 'Nenhum arquivo foi enviado.',
];
$mensagemErro = $mensagensErro[$arquivoEnviado['error']] ?? 'Erro desconhecido durante o upload.';
return ['sucesso' => false, 'mensagem' => $mensagemErro];
}
// Valida o tamanho máximo do arquivo
if ($tamanhoMaximo > 0 && $arquivoEnviado['size'] > $tamanhoMaximo) {
return ['sucesso' => false, 'mensagem' => 'O arquivo ultrapassa o tamanho máximo permitido.'];
}
// Obtém e valida a extensão do arquivo
$nomeOriginal = $arquivoEnviado['name'];
$extensaoArquivo = strtolower(pathinfo($nomeOriginal, PATHINFO_EXTENSION));
if (!empty($extensoesPermitidas) && !in_array($extensaoArquivo, $extensoesPermitidas)) {
return ['sucesso' => false, 'mensagem' => 'Extensão de arquivo não permitida.'];
}
// Verifica o tipo MIME real do arquivo
if (!empty($tiposMimePermitidos)) {
$finfo = new finfo(FILEINFO_MIME_TYPE);
$tipoMime = $finfo->file($arquivoEnviado['tmp_name']);
if (!in_array($tipoMime, $tiposMimePermitidos)) {
return ['sucesso' => false, 'mensagem' => 'Tipo de arquivo inválido.'];
}
}
// Gera um nome de arquivo único e seguro para evitar ataques
$nomeSeguro = bin2hex(random_bytes(12)) . '.' . $extensaoArquivo;
// Verifica se o diretório de destino existe e é gravável
$caminhoDestino = rtrim($diretorioDestino, '/') . '/';
if (!is_dir($caminhoDestino) || !is_writable($caminhoDestino)) {
return ['sucesso' => false, 'mensagem' => 'O diretório de upload não está disponível ou não tem permissão de escrita.'];
}
// Para imagens, realiza validação adicional usando a biblioteca GD
if (in_array($tipoMime, ['image/jpeg', 'image/png', 'image/gif'])) {
$infoImagem = getimagesize($arquivoEnviado['tmp_name']);
if (!$infoImagem) {
return ['sucesso' => false, 'mensagem' => 'O arquivo de imagem está corrompido ou não é válido.'];
}
// Descomente para validação mais rigorosa, como criar um recurso temporário
// $imagemTemp = imagecreatefromstring(file_get_contents($arquivoEnviado['tmp_name']));
// if (!$imagemTemp) {
// return ['sucesso' => false, 'mensagem' => 'Falha ao processar a imagem.'];
// }
// imagedestroy($imagemTemp);
}
// Move o arquivo para o diretório final
$caminhoArquivo = $caminhoDestino . $nomeSeguro;
if (!move_uploaded_file($arquivoEnviado['tmp_name'], $caminhoArquivo)) {
return ['sucesso' => false, 'mensagem' => 'Falha ao mover o arquivo para o destino.'];
}
return [
'sucesso' => true,
'mensagem' => 'Upload realizado com sucesso.',
'nome_arquivo' => $nomeSeguro,
'caminho_completo' => $caminhoArquivo,
];
}
Exemplo de Utilização
<?php
// Configurações para o upload
$diretorio = './uploads';
$extensoes = ['jpg', 'jpeg', 'png'];
$tamanhoLimite = 5 * 1024 * 1024; // 5MB em bytes
$mimeTypes = ['image/jpeg', 'image/png'];
// Processa o upload se a requisição for POST
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['arquivo'])) {
$resultado = processarUpload('arquivo', $diretorio, $extensoes, $tamanhoLimite, $mimeTypes);
if ($resultado['sucesso']) {
echo 'Arquivo salvo em: ' . htmlspecialchars($resultado['caminho_completo']);
} else {
echo 'Erro: ' . htmlspecialchars($resultado['mensagem']);
}
}