Pergunta

Eu estou escrevendo um script PHP que gera arquivos gzipped. A abordagem que eu tenho usado é construir uma string em PHP e gzcompress () da cadeia antes de escrevê-lo em um arquivo no final do script.

Agora eu estou testando meu script com arquivos maiores e correr em erros de alocação de memória. Parece que a string de resultado está se tornando grande demais para segurar na memória de uma vez.

Para resolver este eu tentei usar gzopen () e gzwrite () para evitar a alocação de uma grande cadeia de PHP. No entanto, o arquivo compactado gerado com gzwrite () é muito diferente de quando eu uso gzcompress (). Eu experimentei com diferentes níveis zip, mas isso não ajuda. Eu também tentei usando gzdeflate () e acabar com os mesmos resultados que gzwrite (), mas ainda não é semelhante ao gzcompress (). Não é apenas os dois primeiros bytes (cabeçalho zlib) que são diferentes, é o arquivo inteiro.

O que gzcompress () fazer diferente destas outras funções gzip em PHP? Existe uma maneira que eu possa imitar os resultados de gzcompress () enquanto incrementalmente produzir o resultado?

Foi útil?

Solução

Não estou 100% certo, mas meu palpite é que gzcompress usa o formato GZIP, e gzopen / gzwrite usar ZLIB. Honestamente, eu não posso te dizer qual é a diferença entre os dois é, mas eu sei que GZIP utiliza ZLIB para a compressão real.

É possível que nada disso importa embora. Tente criar um arquivo gzip com gzopen / gzwrite e, em seguida, descompactá-lo usando o programa gzip de linha de comando. Se ele funciona, em seguida, usando gzopen / gzwrite irá trabalhar para você.

Outras dicas

A principal diferença é que os iniciados função gzwrite ZLIB com a opção SYNC_FLUSH, que irá almofada a saída para um limite de 4 bytes (ou é 2), e em seguida um pouco mais (0x00 0x00 0x03 0xFF 0xFF).

Se você estiver usando-os para criar arquivos zip, tomar cuidado para que o utilitário padrão Mac Archive não aceita esse formato.

Do que eu posso dizer, SYNC_FLUSH é uma opção gzip, e não é permitido no formato PKZip / Info-ZIP, todos os arquivos .zip e seus derivados vêm.

Se você esvaziar um pequeno arquivo / texto, resultando em um único bloco desinflar, e compará-lo com o mesmo texto escrito com gzwrite, você verá 2 diferenças, um dos bytes no cabeçalho do bloco deflate é diferente até 1, e a extremidade é preenchido com os bytes acima. Se o resultado for maior do que um bloco de desinflar, as diferenças começam a estacada. É difícil fixar este, como os cabeçalhos do bloco de transmissão de desinsuflação não são mesmo byte alinhados. Há uma razão para todo mundo usa o zlib. Poucas pessoas são corajosos o suficiente para sequer tentar reescrever esse formato!

Eu tive um problema semelhante uma vez - basicamente não havia memória RAM suficiente alocada para PHP para fazer o negócio.

I acabou salvando a cadeia como um arquivo de texto, em seguida, usando exec () para gzip o arquivo usando o sistema de arquivos. A sua não é uma solução ideal, mas ele trabalhou para a minha situação.

tente aumentar o parâmetro memory_limit no seu arquivo php.ini

Ambos gzcompress () e gzopen () usar o método DEFLATE para comprimir os blocos. Mas eles têm diferentes cabeçalho / trailer.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top