Search code examples
phpcsvphp-stream-wrappers

PHP: Writing to a CSV file while stream headers are in a function


I'm attempting to write an SQL query to a CSV file in PHP. I have had this this working, thanks to some advice [in a previous question][1]. However I'm attempting to reduce repetition in my code were possible from the previous example.

I'm creating headers/stream wrapper in a function here:

function csvCreate($filename){
    header("Cache=Control: must-revalidate, post-check=0, pre-check=0");
    header('Content-Description: File Transfer');
    header("Content-type: text/csv");
    header("Content-Disposition: attachment; filename={$filename}");
    header("Expires: 0");
    header("Pragma: public");
    $fh = @fopen( 'php://output', 'w' );
}

I'm then calling the function in a conditional statement and passing $filename as a parameter here:

if(isset($_POST["Submit"]) && ($_POST['Weight'] == 'Weight'))
{
    //csvCreate->$fileName .= 'OutputWeightNull.csv';
    csvCreate('OutputWeightNull.csv');
    $query = mysqli_query($conn, 'SELECT * FROM  `bfi_product_volumne_data` WHERE weight = 0 OR weight IS NULL') or die(mysqli_error($conn));
    if ($result = mysqli_fetch_array($query,MYSQLI_ASSOC))
    {
        fputcsv($fh, array_keys($result));
        fputcsv($fh, $result);
        while ($result = mysqli_fetch_array($query,MYSQLI_ASSOC))
        {
            fputcsv($fh, $result);
        }
    }
}

The problem is data is not being written to the CSV. My feeling is I need to point the 'fputcsv' call to the function. I've attempted this using 'csvCreate->fputcsv' which doesn't appear to work. Could anyone suggest what the issue could be here. Thanks

  [1]: http://stackoverflow.com/questions/33433737/php-writing-a-mysql-query-to-cs

Solution

  • The problem is that you create file pointer $fh inside the function. So it is only visible inside the function and not outside of the function (as it probably was before you put the code to the function). You need to pass that variable from the function to the outer world. It can be done with return. Then in the 'outer' world you need to assign that returned value to the variable in the 'outer' scope and use it.

    You need to pass $fh outside of the function. I.e.

    function csvCreate($filename){
        // .. rest of the code
        $fh = @fopen( 'php://output', 'w' );
        return $fh;
    }
    

    then in the code where you write to output do the following making $fh visible in that scope.

    // .. rest of the code
    $fh = csvCreate('OutputWeightNull.csv');
    // .. rest of the code