Manipular um arquivo na memória com PHP (sem criar um arquivo temporário no disco)

StackOverflow https://stackoverflow.com/questions/1189019

  •  19-09-2019
  •  | 
  •  

Pergunta

Estou tentando gerar um arquivo on-the-fly no PHP e enviá-lo ao usuário imediatamente (sem salvá-lo). Imaginei que não haveria necessidade de criar um arquivo no disco, pois os dados que estou enviando não são persistentes de qualquer maneira, no entanto, ao pesquisar na Web, não consegui descobrir como. Eu também não me importo com o formato de arquivo.

Então, a questão é:

É possível criar e manipular um arquivo de arquivo na memória dentro de um script PHP sem criar um tempfile ao longo do caminho?

Foi útil?

Solução

Eu tive o mesmo problema, mas finalmente encontrei uma solução um tanto obscura e decidi compartilhá -la aqui.

Eu vim acumular o grande zip.lib.php/unzip.lib.php scripts que vêm com phpmyadmin e estão localizados no diretório "bibliotecas".

Usando zip.lib.php trabalhou como um charme para mim:

require_once(LIBS_DIR . 'zip.lib.php');

... 

//create the zip
$zip = new zipfile();

//add files to the zip, passing file contents, not actual files
$zip->addFile($file_content, $file_name);

...

//prepare the proper content type
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=my_archive.zip");
header("Content-Description: Files of an applicant");

//get the zip content and send it back to the browser
echo $zip->file();

Esse script permite o download de um zip, sem a necessidade de ter os arquivos como arquivos reais ou salvar o zip como um arquivo.

É uma pena que essa funcionalidade não faça parte de uma biblioteca PHP mais genérica.

Aqui está um link para o zip.lib.php Arquivo da fonte PhpMyadmin:https://github.com/phpmyadmin/phpmyadmin/blob/release_4_5_5_1/libraries/zip.lib.php

ATUALIZAR:Certifique -se de remover a seguinte verificação desde o início do zip.lib.php, caso contrário, o script acaba de terminar:

if (! defined('PHPMYADMIN')) {
    exit;
}

ATUALIZAR:Este código também está disponível no projeto CodeIgniter:https://github.com/patricksavalle/codeigniter/blob/439ac3a87a448e6c2cbae0890c9f672efcae32d/system/helpers/zip_helper.php

Outras dicas

O que você está usando para gerar o arquivo? Você pode usar o fluxo php: // temp ou php: // memória para ler e escrever para/para o arquivo.

Ver http://php.net/manual/en/wrappers.php.php

Em relação ao seu comentário de que o PHP: // temp funciona para você, exceto quando você o fechar, tente mantê -lo aberto, liberando a saída, depois recupere -o para 0 e leia -o.

Procure aqui mais exemplos: http://us.php.net/manual/en/function.tmpfile.php

Também pesquise o buffer de saída e captura: http://us.php.net/manual/en/function.ob-start.php

Você precisa usar ZipArchive::addFromString - se você usar addFile() O arquivo não é realmente adicionado até você ir para fechá -lo. (Bug horrível IMHO, e se você estiver tentando mover arquivos para um zip e excluí -los antes de fechar o zíper ...)
o addFromString() O método o adiciona ao arquivo imediatamente.

Existe realmente um problema de desempenho aqui, ou apenas ofende seu senso de correção? Muitos processos escrevem arquivos temporários e os excluem, e muitas vezes nunca atingem o disco devido ao cache.

Um tempfile é excluído automaticamente quando fechado. Isso é a natureza.

Há apenas duas maneiras pelas quais posso pensar para criar um arquivo ZIP na memória e servir -o e ambos provavelmente são mais problemas do que valem.

  • Use um disco RAM.
  • Modifique a classe Ziparchive para adicionar um método que faça tudo o que o método Close () faz, exceto realmente feche o arquivo. (Ou adicione um parâmetro de licença para fechar ()).
    Isso pode até não ser possível, dependendo das bibliotecas C subjacentes.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top