Search code examples
phpcsvphpmailer

I'm creating a .csv file using fputcsv() and I would like to use AddAttachment() in PHPMailer to send it off automatically


I've edited the original post, hopefully this is more to the point. I would like to drop the .csv file created by fputcsv() and drop it into AddAttachment and send off. Or, if you know how to take the .csv file created and send it to a directory on the server that would be fine too. I think the most direct question is how do I take the results of fputcsv() and drop it into AddAttachments? Do I use temp file?

header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="file.csv"');
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');

        $csvoutput = fopen('php://output', 'w');
        $row = getRow($result3);
        $headers = array_keys($row);
        fputcsv($csvoutput, $headers);
            
               while ($row = getRow($result3)) {
    
                    fputcsv($csvoutput, $row);
    
                }

$mail = new PHPMailer();
$mail->IsSMTP();
$mail->Host       = "smtp.website.com";
$mail->Port       = 587;
$mail->SMTPAuth   = true;
$mail->SMTPSecure = "tls";
$mail->Username   = $email_user;
$mail->Password   = $email_pass;
$mail->SetFrom("example@example.com", "Ex");
$mail->AddAddress("example@example.com", "Ex");
$mail->isHTML(true);
$mail->WordWrap = 50;
$mail->Subject    = "Example";
$mail->Body       = "Example";
$result = $mail->Send();



fclose($csvoutput);
exit;

Do I need the headers() if I'm not downloading it to the page?

header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="file.csv"');
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');

Also, I know this needs to be changed:

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

Please be as detailed as possible, I am unfamiliar with working with files and I couldnt find a tutorial specific to this.


Solution

  • You can't read back from php://output. Save the CSV to a temp file:

    $filename = tempnam(sys_get_temp_dir(), 'my_script_');
    $csvoutput = fopen($filename, 'w');
    

    And then reference that file's path in the AddAttachment() call:

    $mail->addAttachment($filename);
    unlink($filename);
    

    Alternatively, if you don't want to mess with temp files, you can use output buffering to capture standard out. (Since fputcsv() can't output directly to string.)

    ob_start();
    $fp = fopen('php://output', 'w');
    while (...) {
        fputcsv(...);
    }
    fclose($fp);
    $csv_string = ob_get_contents();
    ob_end_clean();
    
    $mail->addStringAttachment($csv_string,"file_name.csv");
    

    Update:

    You're probably doing something like this:

    $filename = tempnam(sys_get_temp_dir(), 'my_script.csv');
    

    Which gives you /tmp/my_script.csvPFj1Lw

    You want to do something like this:

    $filename = tempnam(sys_get_temp_dir(), 'my_script_') . '.csv';
    

    Which gives you /tmp/my_script_H5GVJp.csv

    The reason you want the random characters there is to avoid collisions in case you have more than one instance of the script running at the same time.