[PHP] - Upload de Arquivos em PHP

Encontrei esta explicação de como fazer upload de arquivos em PHP de forma estupidamente simples do que aqueles arquivos que enviei. O meu único problema está sendo como enviar arquivos grandes. Eu já fiz as alterações nas devidas linhas do PHP (php.ini -> upload_max_filesize = 8000M , php.ini -> post_max_size = 8000M , php.ini -> max_execution_time = 3000), só que não funcionou, pois só conigo upar no máximo 8 megas. 

Por enquanto eu desisti de fazer o servidor de ftp porque eu não estou conseguindo criar o usuário de fora do Linux. Dê uma olhada neste script que deve te atender também. Quando eu terminar o que quero, lhe passo o código.


Upload de arquivos com PHP

janeiro 1st, 2009 | by DragaO~ |

Neste tópico ensinarei um modo prático de fazer upload de arquivos apenas utilizando PHP sem a necessidade de um banco de dados :D

bom, antes de mais nada, precisamos de um formulário para enviar nossos arquivos né ? ;)
vamos salvar o arquivo abaixo como “formulario.php” :

1
2
3
4
5
6
7
8
9
10
11
12
13
 DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Formul&aacute;rio de Upload de Arquivotitle>
head>
<body>
<form action="envia_arquivo.php" method="post" enctype="multipart/form-data">
<input type="file" name="arquivo" />
<input type="submit" value="Fazer Upload" />
form>
body>
html>

pronto, algo bastante simples ;)

mas…pera ai, o que eh aquilo tudo na linha 8?

bom, vamos direto ao que interessa :D

8
<form action="envia_arquivo.php" method="post" enctype="multipart/form-data">
  • a tag “form” é utilizada para criar formulários
  • a tag “form” recebe diversos parâmetros, entre eles estão :
    • action : responsável por especificar qual arquivo/script será o responsável por tratar os dados contidos no formulário; o padrão é o próprio arquivo a ser executado (no caso, “formulario.php”)
    • method : pode ser “get” ou “post”, serve para especificar qual o método de envio das variaveis e valores para a página de tratamento de dados; o padrão é “get”
    • enctype : especifica o método de encode dos dados, pode ser “application/x-www-form-urlencoded” ou “multipart/form-data”; o padrão é “application/x-www-form-urlencoded”

todos formulários devem possuir, no mínimo, estes três parâmetros (caso você não especifique algum deles, o valor padrão será utilizado)
o mais importante de tudo é que, um formulário de upload de arquivos deve possuir enctype do tipo “multipart/form-data”, pois este tipo de encode é utilizado para o envio de formulários com grandes quantidades de informação, que é o nosso caso ;)

a especificação da W3C contém o seguinte texto (traduzido por mim) :

O tipo de conteúdo (”content type”) “application/x=www-form-urlencoded” é ineficiente para mandar grandes quantidades de dados binários ou textos que contenham caracteres não-ASCII. O tipo de conteúdo (”content type”) “multipart/form-data” deve ser usado para envio de formulários que possuem arquivos, dados não-ASCII, e dados binários.

O conteúdo “multipart/form-data” segue as regras de todos fluxos de dados MIME como descritos em [RFC2045]. A definição de “multipart/form-data” está disponível no registro [IANA].

Uma mensagem “multipart/form-data” contém uma série de partes, cada uma representando um controle de sucesso. As partes são mandadas para o agente de processamento na mesma ordem que aparece no documento de entrada. Não deve ocorrer interrupção em nenhum dos dados; como isto é feito sai do propósito desta especificação.

texto original :

The content type “application/x-www-form-urlencoded” is inefficient for sending large quantities of binary data or text containing non-ASCII characters. The content type “multipart/form-data” should be used for submitting forms that contain files, non-ASCII data, and binary data.

The content “multipart/form-data” follows the rules of all multipart MIME data streams as outlined in [RFC2045]. The definition of “multipart/form-data” is available at the [IANA] registry.

A “multipart/form-data” message contains a series of parts, each representing a successful control. The parts are sent to the processing agent in the same order the corresponding controls appear in the document stream. Part boundaries should not occur in any of the data; how this is done lies outside the scope of this specification.

isso basicamente diz, que ao utilizar-mos dados que não sejam apenas texto puro, devemos utilizar “multipart/form-data” e não “application/x-form-www-urlencoded”
para a explicação completa da W3C sobre formulários, clique aqui (caso tenha interesse apenas nessa parte sobre o “enctype”, clique aqui)

9
<input type="file" name="arquivo" />

nessa linha estamos criando um campo para escolher um arquivo a ser enviado ao servidor, e estamos definindo o nome deste campo para “arquivo”

10
<input type="submit" value="Fazer Upload" />

para enviar o formulário nós precisamos de um botão para ser clicado, e aqui estamos criando justamente ele, o botão :)

o restante é apenas bom e puro HTML, portanto creio que dispense explicações, até mesmo porque, caso você não saiba, aconselho que estude HTML antes de tentar passar pro PHP

agora vamos, finalmente, criar o arquivo “envia_arquivo.php”, que vai ser o responsável pelo tratamento e envio do arquivo ao servidor :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

//nome da pasta onde vao ficar armazenados os arquivos
$pasta = "uploads";
 
//como estamos apenas enviando um arquivo, basta que a variavel superglobal "$_FILES['arquivo']
//exista para que possamos efetuar o upload
if($_FILES['arquivo']['tmp_name'])
{
//atribuindo o nome do arquivo
$nome = $_FILES['arquivo']['name'];
//movendo o arquivo para o local especificado
if(move_uploaded_file($_FILES['arquivo']['tmp_name'], $pasta."/".$nome))
{
echo "Arquivo movido";
}
else
{
echo "Falha ao mover arquivo";
}
}
?>

simples, rápido, prático e indolor ;)
agora, explicando as linhas :

3
$pasta = "uploads";

aqui estamos apenas definindo o nome da pasta onde ficarão os uploads (lembre-se, neste exemplo, a pasta deve existir)

7
if($_FILES['arquivo']['tmp_name'])

aqui estamos fazendo um teste simples para verificar a existência de um arquivo vindo pelo formulário
agora devemos parar um pouco para falar sobre o array superglobal “FILES”

o array superglobal “FILES” existe (assim como “GET” e “POST”) em todos scripts PHP, querendo ou não eles estão lá e podem ser acessados à qualquer momento (conter ou não algum valor é outra história)
acontece que o array “FILES” possui algumas dimensões, são elas :

$_FILES['arquivo']['name']

responsável por armazenar o nome original do arquivo enviado (algo como “Minha foto.jpg”)

$_FILES['arquivo']['tmp_name']

responsável por conter o caminho completo para o arquivo no servidor (algo como “/tmp/JECpR5.tmp”)

$_FILES['arquivo']['type']

responsável por conter o tipo MIME do arquivo enviado (algo como “image/jpg”)

$_FILES['arquivo']['size']

responsável por conter o tamanho (em bytes) do arquivo (algo como ” 52728? para caso a imagem tenha “52 Kb”)

$_FILES['arquivo']['error']

quando occorrer algum erro, esta variável vai conter o código do erro (para a lista completa de códigos, veja isso)

caso nenhum arquivo tenha sido enviado, nao irá cair nesse “if”, pois essa dimensão do array é composta pelo nome do arquivo temporário criado pelo PHP

10
$nome = $_FILES['arquivo']['name'];

nesta linha estamos atribuindo a variável que vai conter o nome do arquivo
neste exemplo optei por deixar o nome original do arquivo, pois este exemplo apenas possui fins de aprendizado, não é aconselhado deixar os nomes originais de arquivos, algumas dicas:

  1. nomes com espaços não são legais, acreditem
  2. o PHP é case-sensitive (diferencia “m” de “M”), portanto, não é interessante ter um arquivo chamado “MinHaFeXtiNha.JPG”, pois, acreditem, fica deselegante (e também deixa as coisas mais “desorganizadas” e “sem padrão)
  3. quando for trabalhar com banco de dados, deve-se otimizar ao máximo o espaço utilizado, e é muito comum que os programadores (ao menos eu) armazenem apenas o nome do arquivo e nao sua extensão, pois presume-se que as extensões serão sempre as mesmas (ou separa por pasta com a extensão, sei lá, mas pense sempre em manter tudo organizadinho para quando for necessário uma manutenção não ficar perdendo horas com problemas de organização (que acriditem, são muito constantes e chatos de resolver))
  4. eu particularmente, utilizo a função “mktime()” para gerar os nomes dos arquivos e nunca tive problemas, mas lembre-se de, caso o sistema tenha a possibilidade de ter muitos usuários simultâneos enviando arquivos, concatenar algo ao nome do arquivo, evitando assim replicação de arquivos

lembre-se que isso são apenas minhas dicas, não estou obrigando ninguém a segui-las ;)

12
if(move_uploaded_file($_FILES['arquivo']['tmp_name'], $pasta."/".$nome))

nessa linha é que está todo o “trabalho” :D
a função “move_uploaded_file()” move um arquivo (vindo de um formulário) de um lugar para o outro, no nosso caso, estamos movendo o arquivo temporario criado pelo PHP para a pasta que nós queremos e deixando o nome original do arquivo (mas poderíamos facilmente especificar o nome e extensão desejadas, como por exemplo, utilizar a função “mktime()” para gerar nomes que (praticamente) nunca se repitam (pois podem haver múltiplas pessoas enviando arquivos no mesmo segundo, e devemos estar “prontos” para lidar com isso))

13
14
15
16
17
18
19
    {
echo "Arquivo movido";
}
else
{
echo "Falha ao mover arquivo";
}

aqui apenas estamos mostrando uma mensagem de sucesso ou erro, acho que não tem muito o que explicar ;)

agora, além de enviar os arquivos, devemos mostra-los para que a pessoa possa ve-los em outra página, para isto, já fiz um tutorial que se chama Mostrando o Conteúdo de Pastas/Diretórios com PHP e que ensina passo-a-passo como mostrar os arquivos contidos em uma pasta (que é exatamente o que queremos)

manuais da W3C:
Especificação sobre FormuláriosEspecificação sobre o “enctype”

referência das funções:
move_uploaded_file()“, “mktime()

bom, fico por aqui com este tutorial, até a próxima
e lembre-se : problemas? reporte; dúvidas? pergunte :D

 

.