Gerenciamento de envio de arquivos Envio de arquivos com o método POST Este recurso permite realizar envios de arquivos de texto e binários. Com as funções de autenticação e manipulação de arquivos do PHP, você tem o controle completo de quem pode fazer o envio e o que deve ser feito com o arquivo após o envio estar completo. O PHP é capaz de receber envios de arquivos de qualquer navegador compatível com RFC-1867. Nota Sobre Configurações Relacionadas Veja também as diretivas file_uploads, upload_max_filesize, upload_tmp_dir, post_max_size, max_input_time no &php.ini; O PHP também suporta o método PUT para envio de arquivos como o usado pelo Netscape Composer e clientes para Amaya W3C. Veja Suporte ao Método PUT para maiores detalhes. Formulário para Envio de Arquivo Uma interface para envio de arquivo pode ser criada com um formulário especial parecido com este:
Enviar esse arquivo:
]]>
O parâmetro __URL__ no exemplo acima deve ser substituído e apontar para um arquivo PHP. O campo escondido (input type="hidden") MAX_FILE_SIZE (medido em bytes) deve preceder o campo de entrada do arquivo (input type="file"), e o seu valor é o tamanho limite aceito pelo PHP. Este elemento do formulário deve sempre ser usado para evitar que usuários tenham o problema de ter que esperar pela transferência de um arquivo para só então descobrir que ele era grande demais e a transferência falhar. Fique ciente: é muito simples burlar esse parâmetro pelo lado do navegador, portanto nunca dependa exclusivamente desse recurso para bloquear arquivos com maior tamanho. Isso é um recurso meramente conveniente para usuários da aplicação no lado do cliente. Os parâmetros do PHP (no servidor) para "maximum-size", no entanto, não podem ser burlados.
Tenha certeza que seu formulário de envio tenha o atributo enctype="multipart/form-data" do contrário o envio não irá funcionar. A variável global $_FILES conterá toda a informação do arquivo enviado. O conteúdo do formulário de exemplo acima será como o exemplo descrito abaixo. Note que isso assume o nome do arquivo enviado userfile, como foi usado no script de exemplo acima, contudo isso pode ter qualquer nome. $_FILES['userfile']['name'] O nome original do arquivo na máquina do cliente. $_FILES['userfile']['type'] O tipo mime do arquivo, se o navegador fornecer essa informação. Um exemplo poderia ser "image/gif". O tipo mime não é verificado pelo PHP portanto não considere que esse valor será concedido. $_FILES['userfile']['size'] O tamanho, em bytes, do arquivo enviado. $_FILES['userfile']['tmp_name'] O nome temporário com o qual o arquivo enviado foi armazenado no servidor. $_FILES['userfile']['error'] O código de erro associado a esse envio de arquivo. $_FILES['userfile']['full_path'] O caminho completo conforme enviado pelo navegador. Esse valor nem sempre contém uma estrutura de diretórios real, e não se pode confiar nele. Disponível a partir do PHP 8.1.0. Os arquivos serão guardados por padrão no diretório temporário do servidor, a menos que outro local seja especificado através da diretiva upload_tmp_dir no &php.ini;. O diretório padrão do servidor pode ser alterado através da configuração da variável de ambiente TMPDIR no ambiente onde o PHP está sendo executado. Configurando isso usando putenv em um script PHP não irá funcionar. Esta variável de ambiente também pode ser usada para certificar que outras operações também estão funcionando nos arquivos enviados. Validando o envio de arquivos Veja também as funções is_uploaded_file e move_uploaded_file para maiores informações. O exemplo a seguir irá processar o envio de um arquivo que vem de um formulário. '; if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) { echo "Arquivo válido e enviado com sucesso.\n"; } else { echo "Possível ataque de upload de arquivo!\n"; } echo 'Aqui está mais informações de debug:'; print_r($_FILES); print ""; ?> ]]> O script PHP que recebe o arquivo enviado deve implementar qualquer lógica que for necessária para determinar o que deve ser feito com o arquivo enviado. Você pode, por exemplo, usar a variável $_FILES['userfile']['size'] para descartar qualquer arquivo que seja muito pequeno ou muito grande. Você pode usar a variável $_FILES['userfile']['type'] para descartar arquivos incompatíveis com um determinado critério, mas use isso apenas como a primeira de uma série de verificações, porque esse valor está totalmente sob o controle do cliente e não é verificado pelo PHP. Você também pode usar $_FILES['userfile']['error'] e planejar sua lógica de acordo com os Códigos de erro. Independente da lógica, você também deve apagar o arquivo do diretório temporário ou movê-lo para outro local. Se nenhum arquivo for selecionado em seu formulário, o PHP irá retornar $_FILES['userfile']['size'] como 0, e $_FILES['userfile']['tmp_name'] como "none" (nenhum). O arquivo será excluído do diretório temporário ao fim da requisição se ele não for movido ou renomeado. Enviando um array de arquivos O PHP suporta array HTML mesmo com arquivos.

Imagens:

]]>
$error) { if ($error == UPLOAD_ERR_OK) { $tmp_name = $_FILES["pictures"]["tmp_name"][$key]; // basename() pode prevenir ataques de percorrer o sistema de arquivos, // mas mais validações são necessárias $name = basename($_FILES["pictures"]["name"][$key]); move_uploaded_file($tmp_name, "data/$name"); } } ?> ]]>
O progresso do envio de arquivos pode ser implementado usando a Sessão de Progresso de Envio.
Explicando mensagens de erro O PHP retorna um código de erro apropriado na array do arquivo. O código de erro pode ser encontrado no segmento error da array que é criada pelo PHP durante o envio do arquivo. Em outras palavras, o erro pode ser encontrado em $_FILES['userfile']['error']. O valor desse código de erro é uma das constantes UPLOAD_ERR_*. Problemas Comuns O item MAX_FILE_SIZE não pode assumir um tamanho de arquivo maior que o tamanho de arquivo configurado em upload_max_filesize no arquivo &php.ini;. O valor padrão é de 2 megabytes. Se um limite de memória está ativo, um valor maior para o limite de memória no parâmetro memory_limit pode ser necessário. Tenha certeza de estabelecer um limite de memória grande o suficiente através do parâmetro memory_limit. Se o tempo máximo de execução definido através do parâmetro max_execution_time for muito pequeno, a execução do script pode ultrapassar o limite de tempo. Tenha certeza de estabelecer um tempo máximo de execução grande o suficiente através do parâmetro max_execution_time. O parâmetro max_execution_time somente afeta o tempo de execução do script em si. Qualquer tempo gasto com atividades que aconteçam fora da execução do script como chamadas de sistema usando system, a função sleep, pesquisas em banco de dados, tempo gasto pelo processo de enviar um arquivo, etc. não são considerados no momento de determinar o limite de tempo máximo de um script em execução. O parâmetro max_input_time define o tempo máximo, em segundos, que é permitido ao script a receber entradas, isto inclui envio de arquivos. Para um arquivo grande, múltiplos arquivos ou usuários com conexões lentas, o padrão de 60 segundos pode ser ultrapassado. Se o parâmetro post_max_size for muito pequeno, arquivos grandes podem não ser carregados. Tenha certeza de definir o parâmetro post_max_size grande o suficiente. O parâmetro max_file_uploads controla o número máximo de arquivos que podem ser enviados em uma única requisição. Caso sejam enviados mais arquivos que o definido neste limite, então $_FILES interrompe o processamento de arquivos uma vez que o limite tenha sido atingido. Por exemplo, se o parâmetro max_file_uploads está definido como 10, então $_FILES nunca possuirá mais de 10 itens. Não validar o arquivo que você está operando pode permitir que os usuários acessem informações sensíveis em outros diretórios. Devido ao grande número de estilos de listagem de diretórios não podemos garantir que arquivos com nomes exóticos (como os que contém espaços) sejam manuseados corretamente. Um desenvolvedor não deve misturar campos comuns de entrada input e campos de envio de arquivo na mesma variável de formulário (usando um nome de campo input como foo[]). Enviando múltiplos arquivos Múltiplos arquivos podem ser enviados usando diferentes nomes (name) para entradas (input). Também é possível carregar vários arquivos simultaneamente e ter a informação automaticamente organizada em arrays. Para isso, é necessário usar a mesma sintaxe das arrays submetidas pelo formulário HTML que você usa para múltiplos selects e checkboxes: Carregando múltiplos arquivos Envie esses arquivos:


]]>
Quando o formulário acima é submetido, os arrays $_FILES['userfile'], $_FILES['userfile']['name'], e $_FILES['userfile']['size'] serão inicializados. Por exemplo, suponha os nomes dos arquivos /home/test/review.html e /home/test/xwp.out. Neste caso, $_FILES['userfile']['name'][0] deve conter o valor review.html, e $_FILES['userfile']['name'][1] deve conter o valor xwp.out. Similarmente, $_FILES['userfile']['size'][0] deve conter o tamanho do arquivo review.html, e assim por diante. $_FILES['userfile']['name'][0], $_FILES['userfile']['tmp_name'][0], $_FILES['userfile']['size'][0], e $_FILES['userfile']['type'][0] também são definidas. O parâmetro max_file_uploads atua como um limite no número de arquivos que podem ser enviados em uma única requisição. Você precisa ter certeza que seu formulário não tentará enviar mais arquivos que o limite definido. Carregando um diretório inteiro Nos campos de carregamento de arquivos HTML, é possível carregar um diretório inteiro com o atributo webkitdirectory. Esse recurso é suportado na maioria dos navegadores modernos. Com a informação full_path, é possível armazenar os caminhos relativos, ou reconstruir o mesmo diretório no servidor. Enviar este diretório:
]]>
O atributo webkitdirectory não é padronizado e não está no roteiro de padronização. Não utilize-o em sites em produção voltados para a Web: ele não funcionará para todos os usuários. Também podem haver grandes incompatibilidades entre implementações e o comportamento pode mudar no futuro. O PHP analisa apenas a informação de caminho relativo enviada pelo navegador/user-agent, e passa essa informação para o array $_FILES. Não há garantia de que os valores no array full_path contenham uma estrutura de diretórios real, e a aplicação PHP não deve confiar nesta informação.
Suporte ao método PUT O PHP oferece suporte para o método HTTP PUT utilizado por alguns clientes para armazenar arquivos em um servidor. Requisições PUT são muito mais simples que o envio de arquivos usando requisições POST, elas se parecem com algo assim: Isso normalmente significaria que o cliente remoto gostaria de salvar o seguinte conteúdo: /path/filename.html em seu diretório web. É óbvio não se tratar de uma boa ideia que o Apache ou o PHP permitam automaticamente que todos sobrescrevam qualquer arquivo em seu diretório web. Então, para considerar isso como uma requisição é necessário dizer ao seu servidor web que você quer que um determinado script PHP cuide dessa requisição. Para fazer isso no Apache utilize a diretiva Script. Ela pode ser colocada quase em qualquer local de seu arquivo de configuração do Apache. Um local comum é dentro de um bloco <Directory> ou talvez dentro de um bloco <VirtualHost>. Uma linha como a seguinte deve funcionar: Isto diz ao Apache para enviar todas as requisições PUT para as URIs que combinem com o contexto dessa linha para o script put.php. Isto assume que o PHP esteja ativo e permite extensões .php. O destino para todas as requisições PUT para esse script deve ser o próprio script, não o nome do arquivo enviado. Com o PHP pode ser feito algo como se segue no script put.php. Isso copia o conteúdo de um arquivo enviado para o arquivo myputfile.ext no servidor. Provavelmente é necessário a realização de algumas verificações e/ou autenticação de usuário antes de realizar essa cópia. Salvando arquivos HTTP PUT ]]> &reftitle.seealso; Segurança do sistema de arquivos