-3

I am using the following guide to try and get data into a csv delimited format, but I am getting some errors. The guide is showing explode and fputcsv used together.

What am I doing wrong?

This is the guide I am using:

https://www.w3schools.com/php/func_filesystem_fputcsv.asp

Errors:

Warning: explode() expects parameter 2 to be string, array given in /home4/public_html/csvTest.php on line 25

Warning: fputcsv() expects parameter 2 to be array, null given in /home4/public_html/csvTest.php on line 25

Code:

$con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql_subscribers = "
    SELECT *
    FROM test_notif
    ORDER BY date_subscribed
";
$subscriber_stmt = $con->prepare($sql_subscribers);
$subscriber_stmt->execute();
$subscriber_rows = $subscriber_stmt->fetchAll(PDO::FETCH_ASSOC);

foreach ($subscriber_rows as $subscriber_row) {
    fputcsv($file,explode(',',$subscriber_row));
}

Full Code:

<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);

$file_name = "subscriber_list.csv";
$file = fopen("subscriber_list.csv","w");

try {
    $servername = 'localhost';
    $usernameCon = '';
    $passwordCon = '';
    $con = new PDO('mysql:host='.$servername.';dbname=', $usernameCon, $passwordCon);

    $con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $sql_subscribers = "
        SELECT *
        FROM test_notif
        ORDER BY date_subscribed
    ";
    $subscriber_stmt = $con->prepare($sql_subscribers);
    $subscriber_stmt->execute();
    $subscriber_rows = $subscriber_stmt->fetchAll(PDO::FETCH_ASSOC);

    foreach ($subscriber_rows as $subscriber_row) {
        //fputcsv($file,explode(',',$subscriber_row));
        fputcsv($file, $subscriber_row);
    }

    header('Content-type: application/octet-stream');
    header("Content-Disposition: attachment; filename='.$file_name.'");

    fclose($file);
}   
catch(PDOException $e) {
    echo "Connection failed: " . $e->getMessage();
}

?>
<body>
    <form action="" name="csvForm" target="csvIframe">
        <input type="submit" value="Download File">
    </form>
    <iframe name="csvIframe" src="">
    </iframe>
</body>
</html>
Paul
  • 3,348
  • 5
  • 32
  • 76
  • Did you __output__ `$subscriber_row`? – u_mulder Jun 05 '19 at 16:04
  • @u_mulder I am not wanting $subscriber_row to be outputted...at least not onto the page. I just want it to be in the csv file. Or are you referring to doing `$subscriber_name = $subscriber_row['name'];` – Paul Jun 05 '19 at 16:06
  • If you __OUTPUT__ `$subscriber_row` you will see that it is __array__ and not a string. Simple isn't it? – u_mulder Jun 05 '19 at 16:07
  • @u_mulder Yes, when doing `echo $subscriber_row;` I just get 'Array' to output. But I don't see where you are getting at. – Paul Jun 05 '19 at 16:19
  • Try writing to 'php://output' instead of a named file. Check this for an example: https://stackoverflow.com/questions/16251625/how-to-create-and-download-a-csv-file-from-php-script `filename=` in the Content-Disposition header does not refer to the file on your server, it's just there as the suggested name in the "save as" dialog. https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#Directives – Don't Panic Jun 05 '19 at 16:31

1 Answers1

2

Second argument to fputcsv (according to what error tells you)

fputcsv() expects parameter 2 to be array

And $subscriber_row is already an array.

So:

foreach ($subscriber_rows as $subscriber_row) {
    fputcsv($file, $subscriber_row);
}

Update: simple example of output file to user:

foreach ($subscriber_rows as $subscriber_row) {
    //fputcsv($file,explode(',',$subscriber_row));
    fputcsv($file, $subscriber_row);
}

header('Content-type: application/octet-stream');
header("Content-Disposition: attachment; filename='.$file_name.'");

fclose($file);

readfile($file_name);
exit;
u_mulder
  • 54,101
  • 5
  • 48
  • 64
  • Ahh gotcha, so you meant just to remove the explode entirely. This took the errors away, but on page load the forced download's contents is the html I have on the page and not the query resulted. – Paul Jun 05 '19 at 16:24
  • I don't see full script but obviously you should __stop__ script execution after outputting your csv data. – u_mulder Jun 05 '19 at 16:26
  • I believe I am doing so with `fclose($file);` unless this isn't correct. I just edited my question with the full code (it isn't much). – Paul Jun 05 '19 at 16:28
  • `fclose($file); die;` `fclose` just __closes file__, but your php-script keeps on running. – u_mulder Jun 05 '19 at 16:30
  • ok that stops the html from showing in the file, but it still doesn't contain anything from the query. – Paul Jun 05 '19 at 16:32
  • Because you put data into a file on server. And do not provide this file for user. – u_mulder Jun 05 '19 at 16:33
  • How would I give the data to the user's file as well? – Paul Jun 05 '19 at 16:35
  • See the update. Also __use the search__, you're not the only one who cannot output file for downloading. – u_mulder Jun 05 '19 at 16:37