Realizar o upload de um arquivo é bem simples, podemos fazer isso, de várias formas, seja via FTP ou utilizando a classe move_uploaded_file, por exemplo.
O processo começa a ficar um pouco complexo quando aplicamos validações de tamanho, tipos de arquivos, existência de diretórios, permissões...e por ai vai, afina, qualquer pessoa pode subir qualquer tipo de porcaria se a gente não aplicar os filtros/validações.
É muito importante ter em mãos, algumas informações, então, veja a seguir algumas perguntas que deve ser feitas, já que é em cima de suas respostas que vamos construir o sistema.
- Que tipo de arquivo está permitido enviar?
- Qual o mimetypes deles?
- Qual tamanho máximo desses arquivos?
- Para onde vamos enviar?
- Qual o tamanho máximo permitido no arquivo de configuração?
- Quantidade máxima de arquivos é permitida?
No geral, é uma série de informações que precisamos levantar, e em nossa videoaula, tudo isso é esclarecido e apresentado de forma bem clara.
MIME Types
O MIME type é o mecanismo para dizer ao cliente a variedade de documentos transmitidos: a extensão de um nome de arquivo não tem significado na web. Portanto, é importante que o servidor esteja configurado corretamente, de modo que o MIME-type correto seja transmitido com cada documento. Os navegadores costumam usar o MIME-type para determinar qual ação usar como padrão para fazer quando um recurso é obtido. Fonte: Documentação Mozilla
Código fonte
A ordem de execução dos arquivos são:
1.O usuário cai direto na página de upload, chamada de index.html, na qual tem seu formulário e após envia-lo, os dados do método POST é enviado para o arquivo subir.php.
2.O arquivo subir.php gaz a instância da classe Upload, e recebe no método construtor a variável global $_FILES, contendo todas as informações de cada arquivo enviado.
3.Por último, chamados o método upload(), na qual podemos passar um parâmetro true para criar nomes aleatórios. Esse método é responsável por validar e enviar o arquivo para a pasta de destino, e ao término, retorna o código de resposta.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Uploads</title>
</head>
<body>
<form action="subir.php" method="post" enctype="multipart/form-data">
<input type="file" name="flArquivo">
<button type="submit">Enviar</button>
</form>
</body>
</html>
subir.php
<?php
//Requisitamos o arquivo com a classe de upload
require_once('upload.php');
//Instância da classe de upload e envio do $_FILES
$upload = new Upload($_FILES['flArquivo']);
//Chamamos o método que faz o envio e atribuimos true para renomear o nosso arquivo
$messageCode = $upload->upload(true);
//Exibimos o a mensagem a partir do código de resposta
echo $upload->getMessage($messageCode);
echo '<br/>';
echo $upload->getFilename();
//Função auxiliar para debugar
function dd($p = [])
{
echo '<pre>';
print_r($p);
echo '</pre>';
}
upload.php
<?php
class Upload
{
//$_FILE[]
private $file;
//Tipo mymes
private $mimeTypes;
//Tamanho máximo do arquivo em Byter
private $maxSize;
//Diretório de publicação
private $path;
//Nome do arquivo gerado
private $fileName;
/**
* Método construtor
*
* @param array $file $_FILES['yourFile']
* @return void
*/
public function __construct($file)
{
$this->file = $file;
$this->mimeTypes = [
'text/plain',
'image/jpeg',
'image/png'
];
$this->maxSize = 2097152; //2MB
$this->path = 'arquivos/';
}
/**
* Método responsável por enviar o arquivo para o servidor
*
* @param bool $rename
* @return int
*/
public function upload(bool $rename = false)
{
$validate = $this->validate();
if ($validate < 0)
return $validate;
if ($rename) {
$ex = explode('.', $this->file['name']);
$this->fileName = uniqid('image_', true) . '.' . end($ex);
} else {
$this->fileName = preg_replace(
'/[^a-z-A-Z0-1._-]/',
'-',
$this->file['name']
);
}
if (!is_dir($this->path))
mkdir($this->path, null, true);
if (!move_uploaded_file(
$this->file['tmp_name'],
$this->path . $this->fileName
))
return -3;
return 1;
}
/**
* Retorna o nome do arquivo
*
* @return string
*/
public function getFilename()
{
return $this->fileName;
}
/**
* Verifica se o arquivo que estamos subindo é válido
*
* @return int
*/
public function validate()
{
$fileType = mime_content_type($this->file['tmp_name']);
if (!in_array($fileType, $this->mimeTypes))
return -1; //Tipo Inválido
if ($this->file['size'] > $this->maxSize)
return -2; //Arquivo muito grandee
return 1;
}
/**
* Retorna uma mensagem a partir do seu código
*
* @param int $code
* @return string
*/
public function getMessage(int $code = null)
{
switch ($code) {
case 1:
return 'Arquivo enviado com sucesso.';
break;
case -1:
return 'O tipo de arquivo é inválido.';
break;
case -2:
return 'O tamanho do arquivo é maior do que o permitido.';
break;
case -3:
return 'Houve um erro ao tentar subir o arquivo.';
break;
}
}
}
Enfim, assim terminamos de enviar o nosso arquivo.