Home > other >  Laravel attach a non-physically saved file
Laravel attach a non-physically saved file

Time:02-11

I'm trying to find a way to attach a non-physical file to an email that's being made on the spot.

I'm using the following lines in my controller:

$columns = ['line1', 'line2'];
$rows    = [
    ['line1' => 'first', 'line2' => 'second'],
    ['line1' => 'first', 'line2' => 'second'],
    ['line1' => 'first', 'line2' => 'second'],
];

Mail::to('[email protected]')->send(new ExportMail($columns, $rows));

And the following build function in the ExportMail class:

public function build()
{
    $file = fopen('php://output', 'w'); // Tried w  too
    fputcsv($file, $this->columns);

    foreach ($this->rows as $row) {
        fputcsv($file, $row);
    }
    

// I tried a couple of things:

    return $this->view('emails.myTestMail')
        ->attach($file);

    return $this->view('emails.myTestMail')
        ->attach(fopen($file, 'r'));

    return $this->view('emails.myTestMail')
        ->attach(fopen('php://output', 'r'));

    return $this->view('emails.myTestMail')
        ->attach(file_get_contents($file));

    return $this->view('emails.myTestMail')
        ->attach(file_get_contents(fopen($file, 'r')));

    return $this->view('emails.myTestMail')
        ->attach(file_get_contents(fopen('php://output', 'r')));
}

But none if it works so I'm beginning to question if there is a way to send an email with a file that is never physically saved.

CodePudding user response:

You can attach file data directly with the attachData method documented here:

https://laravel.com/docs/9.x/mail#raw-data-attachments

I use this regularly to attach dynamically generated PDF files, for example.

You should be able to do something like this:

return $this->view('emails.myTestMail')
    ->attachData($yourCsvData, "attachment.csv");

Also, I think you want to look at how you are generating your CSV data. Right now using php://output the CSV data will be sent out to the browser immediately, not stored in a variable.

There are a couple ways you can solve this, output buffering being one, or using php://temp instead, or using one of many CSV libraries (like https://csv.thephpleague.com/). I put together a fully working example for you here using php://temp:

https://laravelplayground.com/#/snippets/aa5b6594-4493-4ca4-9d12-837c102b7cc5

Expand the rawAttachments attribute on that Message on the right, and you'll see the attached CSV file.

  • Related