symfony/fake-sms-notifier
Symfony Notifier transport that fakes SMS delivery during development. Redirect SMS messages to email (with configurable to/from and optional custom mailer transport) or log them via a logger DSN, without sending real texts.
Install Dependencies:
composer require symfony/notifier symfony/fake-sms-notifier
Note: Laravel does not natively use Symfony Notifier, so this requires a bridge (see Implementation Patterns).
Configure DSN in .env:
# Option 1: Fake SMS as email (sent to your inbox)
FAKE_SMS_DSN=fakesms+email://default?to=dev@example.com&from=TestSMS
# Option 2: Fake SMS as logs (visible in Laravel logs)
FAKE_SMS_DSN=fakesms+logger://default
First Use Case: Testing SMS Notifications Create a test notification class (if using Laravel Notifications) or directly use Symfony Notifier:
// Example using Symfony Notifier (requires bridge)
use Symfony\Component\Notifier\Notifier;
use Symfony\Component\Notifier\Message\SmsMessage;
$notifier = app(Notifier::class);
$notifier->send(new SmsMessage('Hello from fake SMS!', '+1234567890'));
Output: Check your email inbox or Laravel logs (storage/logs/laravel.log) for the fake SMS.
Since Laravel doesn’t natively support Symfony Notifier, create a service provider to integrate them:
// app/Providers/SymfonyNotifierServiceProvider.php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Symfony\Component\Notifier\Notifier;
use Symfony\Component\Notifier\Transport\FakeSmsTransportFactory;
class SymfonyNotifierServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->singleton(Notifier::class, function ($app) {
$dsn = config('services.fake_sms.dsn');
$factory = new FakeSmsTransportFactory();
return new Notifier([$factory->createTransport($dsn)]);
});
}
}
Register in config/app.php:
'providers' => [
App\Providers\SymfonyNotifierServiceProvider::class,
],
Use Laravel’s config to toggle between fake and real SMS transports:
// config/services.php
'fake_sms' => [
'dsn' => env('FAKE_SMS_DSN', 'fakesms+logger://default'),
],
Example Usage:
$notifier = app(Notifier::class);
$notifier->send(new SmsMessage('Test', '+1234567890'));
Extend Laravel’s Notification system to support fake SMS:
// app/Notifications/FakeSmsChannel.php
namespace App\Notifications;
use Illuminate\Notifications\Notification;
use Symfony\Component\Notifier\Notifier;
class FakeSmsChannel
{
public function __construct(private Notifier $notifier) {}
public function send($notifiable, string $message)
{
$this->notifier->send(new \Symfony\Component\Notifier\Message\SmsMessage($message, $notifiable->phone));
}
}
Usage in Notification:
// app/Notifications/SmsVerification.php
use App\Notifications\FakeSmsChannel;
public function via($notifiable)
{
return [new FakeSmsChannel(app(Notifier::class))];
}
Use fake SMS in tests to verify notifications:
// tests/Feature/SmsNotificationTest.php
use Symfony\Component\Notifier\Message\SmsMessage;
public function test_sms_notification()
{
$notifier = app(Notifier::class);
$notifier->send(new SmsMessage('Test', '+1234567890'));
// Assert via email (if using fakesms+email)
$this->assertDatabaseHas('notifications', [
'message' => 'Test',
]);
// OR check logs for fake SMS output.
}
Configure GitHub Actions or other CI tools to use fake SMS for deterministic testing:
# .github/workflows/test.yml
env:
FAKE_SMS_DSN: fakesms+logger://default
Symfony Notifier Dependency Overhead
symfony/notifier (~50+ dependencies) may conflict with existing Laravel packages or increase bundle size.Laravel-Symfony Integration Complexity
Notification system and Symfony Notifier are not drop-in compatible. Expect boilerplate code for bridging.Log Clutter with fakesms+logger
// config/logging.php
'channels' => [
'fake_sms' => [
'driver' => 'single',
'path' => storage_path('logs/fake_sms.log'),
'level' => 'debug',
],
],
Then update the DSN to use a custom logger:
FAKE_SMS_DSN=fakesms+logger://fake_sms
Email Routing Issues with fakesms+email
fakesms+email, ensure the to and from addresses in the DSN are valid and accessible.dev-team+fakesms@example.com) to aggregate fake SMS emails.Phone Number Formatting
+1234567890). Malformed numbers may cause silent failures.use Symfony\Component\Notifier\Bridge\FakeSms\PhoneNumber;
$phone = new PhoneNumber('+1234567890'); // Valid
// $phone = new PhoneNumber('1234567890'); // Invalid (missing '+')
No Support for Attachments or Rich Media
Enable Symfony Notifier Debug Mode
Add this to your config/services.php to log transport creation:
'services' => [
'notifier' => [
'debug' => env('APP_DEBUG', false),
],
],
Inspect Fake SMS Transport Dump the transport object to verify configuration:
$transport = (new FakeSmsTransportFactory())->createTransport(env('FAKE_SMS_DSN'));
dump($transport);
Check for Deprecation Warnings Some older versions of Symfony Notifier may trigger deprecation notices. Update to the latest stable version:
composer require symfony/notifier:^7.0
Custom Transport Backend Extend the package to support additional backends (e.g., Slack, database):
// app/Notifier/FakeSms/SlackTransport.php
namespace App\Notifier\FakeSms;
use Symfony\Component\Notifier\Transport\FakeSmsTransportInterface;
class SlackTransport implements FakeSmsTransportInterface
{
public function send(SmsMessage $message)
{
// Send to Slack webhook
file_get_contents('https://hooks.slack.com/...', json_encode([
'text' => $message->getContent(),
]));
}
}
Register it in your Notifier instance.
Override Default Behavior Use Symfony’s event system to intercept fake SMS messages:
// app/Providers/EventServiceProvider.php
use Symfony\Component\Notifier\EventListener\TransportListener;
protected function shouldDispatch(): array
{
return [
TransportListener::class,
];
}
Laravel Horizon Integration If using queues, ensure fake SMS transports are serializable for queue jobs:
// app/Providers/AppServiceProvider.php
use Illuminate\Contracts\Queue\ShouldQueue;
How can I help you explore Laravel packages today?