Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Falae galera.
Consegui um código na web para fazer o download pelo php://output, mas não sei se o arquivo é muito grande (7Mb) que a tela fica vazia e não ocorre o download.
Este é código:
// output headers so that the file is downloaded rather than displayed
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=data.csv');
// create a file pointer connected to the output stream
$output = fopen('php://output', 'w');
// output the column headings
fputcsv($output, array('Column 1', 'Column 2', 'Column 3'));
// fetch the data
mysql_connect('localhost', 'username', 'password');
mysql_select_db('database');
$rows = mysql_query('SELECT field1,field2,field3 FROM table');
// loop over the rows, outputting them
while ($row = mysql_fetch_assoc($rows)) fputcsv($output, $row);
Mas como mencionei, o arquivo é muito grande, a consulta possui 32 campos e tem mais de 40000 linhas. Estou desde 30/01/2015 para tentar resolver, e nada certo.
Dede já, agradeço a quem puder me ajudar.
Não tenho acesso as configurações do servidor.
No teste localhost* (error_reporting = E_ALL & ~E_NOTICE), criei um vetor com 10000 linhas e 32 colunas, vou postar abaixo:
<?php
include_once("force_csv_download.php");
$header = array();
$data = array();
$columns = 32;
$rows = 10000;
for ( $x = 1 ; $x <= $columns ; $x++ ) {
$header[] = "Column " . $x;
}
for ( $y = 0 ; $y < $rows ; $y++ ) {
for ( $x = 0 ; $x < $columns ; $x++ ) {
$column[ $x ] = "Row " . $y . " Column " . $x;
}
$data[] = $column;
}
print_r(csvDownload($data, "teste_download", $header));
?>
O arquivo com o código da web adaptado:
function csvDownload( $data = array(), $nome_arquivo = "", $header = array() ) {
if( !isset($nome_arquivo) || empty($nome_arquivo) ) {
$nome_arquivo = "teste_" . date("dmY_His");
}
// Cabeçalhos de saída para que o arquivo é baixado, em vez de exibidos
header("Last-Modified: " . gmdate("D,d M YH:i:s") . " GMT");
header("Cache-Control: no-cache, must-revalidate");
header("Content-Type: text/csv; charset=utf-8");
header("Content-Disposition: attachment; filename=" . $nome_arquivo . ".csv");
// Criar um ponteiro de arquivo ligado ao fluxo de saída
$output = fopen("php://output", "w");
// As duas primeiras letras do arquivo não pode ser "ID" (Maiúsculas)
$exemplo = array(
"header" => array("Col 1", "Col 2", "Col 3", "Col 4"),
"rows" => array(
0 => array("R1C1", "R1C2", "R1C3", "R1C4"),
1 => array("R2C1", "R2C2", "R2C3", "R2C4"),
2 => array("R3C1", "R3C2", "R3C3", "R3C4"),
3 => array("R4C1", "R4C2", "R4C3", "R4C4")
)
);
// Testa o valor de $data, deve ser um array com os valores
if ( empty($data) ) {
$header = $exemplo['header'];
$data = $exemplo['rows'];
}
// Títulos do arquivo
if ( !empty($header) ) fputcsv($output, $header);
// Percorre todas as linhas e jogando no arquivo
foreach ( $data as $row ) {
fputcsv($output, $row);
}
fclose($output);
}
Agora o erro:
Fatal error: Allowed memory size of 16777216 bytes exhausted (tried to allocate 35 bytes) in C:\Users\Jean.Jean-PC\Desktop\Coisas Jean\VertrigoServ\www\pci\o&m\teste.php on line 16
Cara, deu pau na minha cabeça, não estou mais conseguindo raciocinar direito mais sobre isso... =/
Espero que consiga abrir minha mente, kkk.
Aumentei o limite de memória pra 128M, e aumentei o número de linhas para 50000 no teste. Ocorreu o mesmo erro (Allowed memory size exhausted):
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 35 bytes) in C:\Users\Jean.Jean-PC\Desktop\Coisas Jean\VertrigoServ\www\pci\o&m\teste.php on line 16
Mas aumentando o tamanho é a única solução? Não há outra forma?
Para ativar a exibição de erros basta:
error_reporting(E_ALL);
ini_set('display_errors', '1');
Se o problema for relacionado a quantidade de memória alocada você não vai conseguir corrigir em uma hospedagem compartilhada... neste caso o caminho é em vez de dar este output direto jogar isto tudo para um arquivo e então forçar o download do arquivo, mas note que isto provavelmente vai esbarrar no timeout da execução do script.Estive vendo o ob_start(), ob_flush() e ob_end_flush(), mas não consegui entender. Nem mesmo com essas funções o problema pode ser solucionado?
Testei seu código aqui e o problema é o memory_limit do servidor, que no seu caso esta em 16M.
Eu sei disso porque coloquei no começo desse seu código essa linha:
ini_set('memory_limit', '16M');
E tive o mesmo erro que você.
Eu tive que colocar 64M pra funcionar, ou remover pois aqui o memory_limit no php.ini esta configurado um valor alto já.
Até mais.
No localhost aumentei para 128M e aumentei a quantidade de linhas pra 50000 e não resolveu...
Estive vendo o ob_start(), ob_flush() e ob_end_flush(), mas não consegui entender. Nem mesmo com essas funções o problema pode ser solucionado?
Se você está estourando o limite de memória com o buffer estas funções não vão resolver.
Faça um teste simples, limite a consulta a 10 linhas, se funcionar sabemos que o código está ok. Assumindo que ele esteja ok, é provável que o timeout esteja sendo alcançado, neste caso ative a exibição de todos os erros para ter certeza do que realmente está ocorrendo.