Generate csv file in php

Asked

Viewed 9,602 times

2

Hello guys I am trying to create a php query in mysql database to generate a csv file according to the code below. The problem is that the part that would download the file is showing error, I already reviewed a few times and did not find the error I made. The file appears in the FTP folder where the index is.

I appreciate any help thank you very much.

<?php
//PDO
$pdo = new PDO('mysql:host=localhost;dbname=banco', 'root', '123456');
$stmt = $pdo->prepare('SELECT * FROM cadastro');   
$stmt->execute();
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);

//Criação do Arquivo csv sobre os dados obtidos de um SQL
$from = fopen("file.csv", 'wb');

foreach ($results as $result) 
{
    $results[$idx] = str_replace("\"", "\"\"", $result);        
    fwrite($from, '"'.implode('";"', $results[$idx]).'"'.PHP_EOL);
    }
   fclose($from);


   header("Content-type: application/csv");   
   header("Content-Disposition: attachment; filename=file.csv");   
   header("Content-Transfer-Encoding: binary");
   header("Pragma: no-cache");
   $path = "file.csv";
   $from = fopen($path, 'r');
   $csv = fread($from, filesize($path));   
   fclose($from);
   echo $csv;
   ?>
  • This question is in the reopening queue. However, looking at the question, the answers and the comments in the answers, I get in doubt. Someone there might give reasons either to reopen or to keep it closed?

2 answers

7


First, let’s eliminate this scam here from the code:

$results[$idx] = str_replace("\"", "\"\"", $result);        

PHP already has the right function for this, which is fputcsv, and other than that, there’s a mistake in the way that your loop.

Besides, if it’s to generate and send to the client, you don’t need create a disk file, just send it to standard output:

$out = fopen('php://output', 'w');

I mean, that’s all it takes:

<?php
   header( 'Content-type: application/csv' );   
   header( 'Content-Disposition: attachment; filename=file.csv' );   
   header( 'Content-Transfer-Encoding: binary' );
   header( 'Pragma: no-cache');

   $pdo = new PDO( 'mysql:host=localhost;dbname=banco', 'root', '123456' );
   $stmt = $pdo->prepare( 'SELECT * FROM cadastro' );   
   $stmt->execute();
   $results = $stmt->fetchAll( PDO::FETCH_ASSOC );

   $out = fopen( 'php://output', 'w' );
   foreach ( $results as $result ) 
   {
      fputcsv( $out, $result );
   }
   fclose( $out );
?>

If you really want to optimize, don’t even need to load everything in memory. Just instead of fetchAll, use fetch and fputcsv line by line in the loop, but then it slips a bit of the question.

Just for the record, if at any time you really need to send a file that’s on disk to the user, you don’t need this fread of your code. PHP has the function readfile() to do it all at once:

header("Content-type: application/csv");   
header("Content-Disposition: attachment; filename=file.csv");   
header("Content-Transfer-Encoding: binary");
header("Pragma: no-cache");
readfile( 'file.csv' );

http://php.net/manual/en/function.readfile.php

  • Thanks for the tips, but when testing my server code test the following error: Warning: Cannot Modify header information - headers already sent by (output Started at /home/public_html/Fab/exportacsv.php:1) in /home/public_html/Fab /exportacsv.php on line 2 - 3 -4 -5. respectively the header lines, very strange.

  • 1

    It is not strange no, this is a classic error of those who do not have a lot of practice with PHP, it happens to a lot of people. It means that your script is sending some data before the headers, which invalidates the use of these. The problem has nothing to do with the answer code, it may be some modification you have made, or a problem in the format you used when saving the file. Understand more here, and see the solutions: Error - Cannot Modify Header Information

  • 1

    It was a blank space before '<? php', as you said before a student’s mistake, thanks for the support I learned something new.

1

Sirs,

I know the question is about generating CSV from PHP, but, I’ve used native solutions in Dbms and liked the result (mainly with a lot of data) there is no access to data by PHP. The script that will trigger this command may even have a cache policy to not run it "every time", of course, depending on what is intended.

In Mysql you solve this problem with a command, of course, since feasible in your solution

SELECT id, description, date
FROM operations
WHERE type = 1
INTO OUTFILE '/tmp/today_ops.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n';

I hope I contributed.

  • 1

    It is worth saying that this solution will generate the CSV on the machine where is running the DB, in case.

  • @Bacco perfectly. Very well observed. It is not always that this solution meets.

  • It goes from the person’s use, really. In cases where DB runs on the same machine, it gets even simpler. In this case, you can take advantage of the second part of what I put in the answer for the person to download the file already generated with the method you proposed. The only care is not to create a race condition of the person accessing the page to download the CSV right at the time it is being updated. Anyway, for things in large volumes that need to be stored, do by DB can avoid the overhead and timeout PHP, as long as DB allows a number with simultaneous connections clearance.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.