Le funzionalità email di Laravel
Le funzionalità email di Laravel sono costruite su Symfony Mailer e supportano driver come SMTP, Mailgun, Postmark, Resend, Amazon SES, sendmail.
SwiftMailer è stato dismesso. Da Laravel 9 si usa Symfony Mailer.
Configura in config/mail.php. Nel .env scegli il driver.
MAIL_MAILER=smtp
MAIL_HOST=smtp.example.com
MAIL_PORT=587
MAIL_USERNAME=your-username
MAIL_PASSWORD=your-password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS="[email protected]"
MAIL_FROM_NAME="${APP_NAME}"
Creare una Mailable
Ogni email inviata è rappresentata da una classe “Mailable”.
php artisan make:mail OrderShipped
In app/Mail/.
Configurazione della Mailable
Contiene envelope(), content(), attachments().
<?php
namespace App\Mail;
use App\Models\Order;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class OrderShipped extends Mailable
{
use Queueable, SerializesModels;
public function __construct(
public Order $order,
) {}
public function envelope(): Envelope
{
return new Envelope(
subject: 'Il tuo ordine è stato spedito',
);
}
public function content(): Content
{
return new Content(
view: 'mail.orders.shipped',
);
}
public function attachments(): array
{
return [];
}
}
Mittente
use Illuminate\Mail\Mailables\Address;
use Illuminate\Mail\Mailables\Envelope;
public function envelope(): Envelope
{
return new Envelope(
from: new Address('[email protected]', 'Shop Support'),
subject: 'Il tuo ordine è stato spedito',
);
}
Mittente globale in config/mail.php.
'from' => [
'address' => env('MAIL_FROM_ADDRESS', '[email protected]'),
'name' => env('MAIL_FROM_NAME', 'Example'),
],
Corpo del messaggio
content() indica una vista Blade. Le proprietà public del costruttore sono disponibili nella vista.
public function content(): Content
{
return new Content(
view: 'mail.orders.shipped',
);
}
Vista Blade (resources/views/mail/orders/shipped.blade.php):
<!DOCTYPE html>
<html>
<body>
<h1>Il tuo ordine è stato spedito</h1>
<p>Numero ordine: {{ $order->id }}</p>
<p>Totale: € {{ number_format($order->total) }}</p>
<p>Grazie per il tuo ordine.</p>
</body>
</html>
Puoi passare dati esplicitamente con with (proprietà protected/private).
public function __construct(
protected Order $order,
) {}
public function content(): Content
{
return new Content(
view: 'mail.orders.shipped',
with: [
'orderId' => $this->order->id,
'total' => $this->order->total,
],
);
}
Invio
Con la facade Mail, usa to() e send().
<?php
namespace App\Http\Controllers;
use App\Mail\OrderShipped;
use App\Models\Order;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
class OrderShipmentController extends Controller
{
public function store(Request $request): RedirectResponse
{
$order = Order::findOrFail($request->order_id);
Mail::to($request->user())->send(new OrderShipped($order));
return redirect('/orders');
}
}
CC e BCC:
Mail::to($request->user())
->cc($ccUsers)
->bcc($bccUsers)
->send(new OrderShipped($order));
Con un mailer specifico:
Mail::mailer('postmark')
->to($request->user())
->send(new OrderShipped($order));
Invio via coda
Mail::to($request->user())->queue(new OrderShipped($order));
Con le code serve la configurazione e il worker attivo.
Con delay:
Mail::to($request->user())
->later(now()->plus(minutes: 10), new OrderShipped($order));
Se la Mailable implementa ShouldQueue, anche send() mette in coda.
use Illuminate\Contracts\Queue\ShouldQueue;
class OrderShipped extends Mailable implements ShouldQueue
{
// ...
}
Connection e coda tramite attribute PHP
Con gli attribute PHP dichiari connection e coda a livello di classe.
use Illuminate\Queue\Attributes\Connection;
use Illuminate\Queue\Attributes\Queue;
#[Connection('sqs')]
#[Queue('emails')]
class OrderShipped extends Mailable implements ShouldQueue
{
// ...
}
Email Markdown
Con il Markdown usi i template Blade responsive di Laravel.
php artisan make:mail OrderShipped --markdown=mail.orders.shipped
use Illuminate\Mail\Mailables\Content;
public function content(): Content
{
return new Content(
markdown: 'mail.orders.shipped',
with: [
'url' => route('orders.show', $this->order),
],
);
}
Template Markdown:
<x-mail::message>
# Il tuo ordine è stato spedito
Ti informiamo che il tuo ordine è stato spedito.
<x-mail::button :url="$url">
Vedi ordine
</x-mail::button>
Grazie,<br>
{{ config('app.name') }}
</x-mail::message>
Componenti disponibili:
| Componente | Descrizione |
|---|
<x-mail::button> | Pulsante link (color: primary, success, error) |
<x-mail::panel> | Riquadro evidenziato |
<x-mail::table> | Tabella in stile Markdown |
Le email Markdown generano automaticamente anche la versione text.
Anteprima delle email
Restituendo l’istanza Mailable da una route puoi visualizzare l’email nel browser.
Route::get('/mailable', function () {
$order = App\Models\Order::first();
return new App\Mail\OrderShipped($order);
});
Email in sviluppo locale
Per non inviare email reali in sviluppo, usa Mailpit.
MAIL_MAILER=smtp
MAIL_HOST=127.0.0.1
MAIL_PORT=1025
Laragon e Laravel Herd includono Mailpit di default.
Con il driver log le email vengono scritte nel file di log: il modo più semplice per verificarle.
Riepilogo
| Obiettivo | Metodo |
|---|
| Creare Mailable | php artisan make:mail ClassName |
| Impostare mittente | envelope() → from |
| Usare template Blade | content() → view |
| Usare Markdown | content() → markdown |
| Inviare | Mail::to()->send() |
| In coda | Mail::to()->queue() |
| Ritardato | Mail::to()->later() |