laminas/laminas-mail
Abandoned Laminas component for composing, parsing, and sending email messages. No further development; use ddeboer/imap for IMAP, zbateson/mail-mime-parser for MIME parsing, and symfony/mailer for sending mail.
Installation:
composer require laminas/laminas-mail
(Note: Due to abandonment, consider alternatives like symfony/mailer for new projects.)
Basic Email Composition:
use Laminas\Mail\Message;
use Laminas\Mail\Transport\Sendmail;
$message = new Message();
$message->setBody('Hello, World!')
->setFrom('sender@example.com')
->addTo('recipient@example.com')
->setSubject('Test Email');
$transport = new Sendmail();
$transport->send($message);
SMTP Transport (Recommended for Production):
use Laminas\Mail\Transport\Smtp;
$transport = new Smtp([
'host' => 'smtp.example.com',
'port' => 587,
'username' => 'user@example.com',
'password' => 'password',
'ssl' => 'tls',
]);
$transport->send($message);
Send a multipart email (HTML + Plaintext fallback):
$message = new Message();
$message->setBody('Plaintext fallback')
->setEncoding('UTF-8')
->getBody()
->setType('text/plain; charset=UTF-8');
$htmlBody = new \Laminas\Mime\Part('HTML content');
$htmlBody->setType('text/html; charset=UTF-8');
$body = new \Laminas\Mime\Message();
$body->setParts([$message->getBody(), $htmlBody]);
$message->setBody($body);
Message Composition:
Laminas\Mail\Message for headers (From, To, Subject).Laminas\Mime\Part:
$attachment = new \Laminas\Mime\Part(file_get_contents('file.pdf'));
$attachment->disposition = \Laminas\Mime\Mime::DISPOSITION_ATTACHMENT;
$attachment->filename = 'file.pdf';
$body->addPart($attachment);
Transport Abstraction:
TransportInterface for APIs (e.g., AWS SES):
class SesTransport implements TransportInterface {
public function send(Message $message) { /* AWS SDK logic */ }
}
Bulk Emails:
$message = new Message();
$message->setFrom('sender@example.com')
->setSubject('Newsletter');
$transport = new Smtp([...]);
foreach ($recipients as $email) {
$clone = clone $message;
$clone->addTo($email);
$transport->send($clone);
}
Laravel Service Provider:
$this->app->singleton('mail.transport', function ($app) {
return new Smtp([
'host' => config('mail.host'),
'port' => config('mail.port'),
// ...
]);
});
Queueable Emails: Use Laravel’s queue system to defer sending:
Mail::queue($message);
(Note: Requires custom queue driver integration.)
Templates:
Combine with laminas/laminas-view for dynamic content:
$view = new \Laminas\View\PhpRenderer();
$html = $view->render('email-template', ['user' => $user]);
$message->setBody($html)->setType('text/html');
Deprecation Warning:
symfony/mailer for new projects.SwiftMailer under the hood (more features).SMTP Timeouts:
$transport = new Smtp([...]);
$transport->setTimeout(30); // 30 seconds
Header Injection:
To/Subject fields to prevent header injection:
$subject = filter_var($userInput, FILTER_SANITIZE_STRING);
$message->setSubject($subject);
Multipart Boundary Issues:
boundary is unique per message:
$body = new \Laminas\Mime\Message();
$body->setBoundary(md5(uniqid()));
Sendmail Quirks:
-f flag explicitly:
$transport = new Sendmail(['from' => 'sender@example.com']);
$transport = new Smtp([...]);
$transport->setDebug(true); // Logs to stderr
File transport to inspect output:
$transport = new \Laminas\Mail\Transport\File('path/to/emails');
$transport->send($message); // Saves to file
Custom Transports:
Implement TransportInterface for APIs (e.g., SendGrid):
class SendGridTransport implements TransportInterface {
public function send(Message $message) {
$client = new \SendGrid\Client(config('services.sendgrid.key'));
$client->send($message->toString());
}
}
Event Listeners:
Extend Laminas\Mail\Message to add pre-send logic:
$message->getEventManager()->attach('send', function ($event) {
$event->getMessage()->addHeader('X-Custom', 'Value');
});
Override Defaults:
Configure transports globally via config/autoload/mail.global.php:
return [
'transports' => [
'smtp' => [
'host' => 'smtp.example.com',
'port' => 587,
],
],
];
$transport = new Smtp([...]);
foreach ($emails as $email) {
$msg = clone $baseMessage;
$msg->addTo($email);
$transport->send($msg);
}
Mail facade:
// app/Facades/Mail.php
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
class Mail extends Facade {
protected static function getFacadeAccessor() {
return 'laminas.mail';
}
}
laminas/mail:
// app/Providers/QueueServiceProvider
$this->app->extend('queue.worker', function ($worker) {
$worker->pushOn('mail', function ($job, $data) {
$transport = app('mail.transport');
$transport->send($job->mail);
});
return $worker;
});
How can I help you explore Laravel packages today?