PHP Examples
Complete, copy-paste examples for every supported PHP queue backend. Each example includes initialization, job processing, in-job logging, and graceful shutdown.
1. Laravel Queues
Zero config — set JOBVIZ_API_KEY
in your .env and the service
provider auto-discovers. All queue connections are monitored automatically.
composer require jobviz/agent // .env
// JOBVIZ_API_KEY=your-api-key
// That's it! The Laravel service provider auto-discovers
// and starts monitoring all queue connections.
// app/Jobs/SendWelcomeEmail.php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Jobviz\Agent\Facades\Jobviz;
class SendWelcomeEmail implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct(
public readonly string $email,
) {}
public function handle(): void
{
// Structured logs appear in the Jobviz timeline
Jobviz::log('Rendering template');
$html = view('emails.welcome', ['email' => $this->email])->render();
Jobviz::log('Sending email', ['to' => $this->email]);
Mail::raw($html, fn ($m) => $m->to($this->email)->subject('Welcome!'));
}
}
// Dispatch from anywhere
SendWelcomeEmail::dispatch('user@example.com');
// Track deployments (e.g. in a deploy script)
// Jobviz::trackDeployment(['version' => '1.2.0', 'commitHash' => 'abc123f']); Tip: Publish the config with
php artisan vendor:publish --tag=jobviz-config
to customise queues, connection, and batching options.
2. Symfony Messenger
Register the SymfonyMessengerProvider
as an event subscriber. It hooks into Messenger's dispatch and worker
events automatically.
composer require jobviz/agent // config/services.yaml
// services:
// Jobviz\Agent\Providers\SymfonyMessengerProvider:
// arguments:
// - '%env(JOBVIZ_API_KEY)%'
// tags:
// - { name: kernel.event_subscriber }
// src/Message/SendWelcomeEmail.php
namespace App\Message;
class SendWelcomeEmail
{
public function __construct(
public readonly string $email,
) {}
}
// src/MessageHandler/SendWelcomeEmailHandler.php
namespace App\MessageHandler;
use App\Message\SendWelcomeEmail;
use Jobviz\Agent\Facades\Jobviz;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
#[AsMessageHandler]
class SendWelcomeEmailHandler
{
public function __invoke(SendWelcomeEmail $message): void
{
Jobviz::log('Rendering template');
$html = $this->twig->render('emails/welcome.html.twig', [
'email' => $message->email,
]);
Jobviz::log('Sending email', ['to' => $message->email]);
$this->mailer->send($html, $message->email);
}
}
// Dispatch from a controller
$bus->dispatch(new SendWelcomeEmail('user@example.com')); 3. Custom provider
Implement the QueueProviderInterface
to integrate any PHP queue or task system. Three methods:
connect(),
disconnect(), and
queues().
<?php
namespace App\Queue;
use Jobviz\Agent\Contracts\QueueProviderInterface;
// 1. Implement the QueueProviderInterface
class CronJobProvider implements QueueProviderInterface
{
private \Closure $push;
private array $timers = [];
public function __construct(
private readonly array $jobs, // [['name' => ..., 'handler' => ...]]
) {}
public function connect(\Closure $push): void
{
$this->push = $push;
foreach ($this->jobs as $job) {
$this->timers[] = $this->schedule($job['cron'], function () use ($job) {
$jobId = $job['name'] . '-' . time();
($this->push)([
'jobId' => $jobId,
'jobName' => $job['name'],
'queue' => 'cron',
'event' => 'active',
'timestamp' => now()->getTimestampMs(),
]);
try {
$result = ($job['handler'])();
($this->push)([
'jobId' => $jobId,
'jobName' => $job['name'],
'queue' => 'cron',
'event' => 'completed',
'timestamp' => now()->getTimestampMs(),
'data' => ['returnValue' => $result],
]);
} catch (\Throwable $e) {
($this->push)([
'jobId' => $jobId,
'jobName' => $job['name'],
'queue' => 'cron',
'event' => 'failed',
'timestamp' => now()->getTimestampMs(),
'data' => [
'failedReason' => $e->getMessage(),
'stack' => $e->getTraceAsString(),
],
]);
}
});
}
}
public function disconnect(): void
{
foreach ($this->timers as $timer) {
$timer->stop();
}
$this->timers = [];
}
public function queues(): array
{
return ['cron'];
}
}
// 2. Use with Jobviz agent
use Jobviz\Agent\JobvizAgent;
$agent = new JobvizAgent(
apiKey: $_ENV['JOBVIZ_API_KEY'],
provider: new CronJobProvider([...]),
);
$agent->start(); Learn more: See the
PHP SDK Guide
for the full QueueProviderInterface
contract and configuration reference.
4. MultiProvider
Combine built-in and custom PHP providers under a single agent. All events appear in the same Jobviz dashboard.
<?php
use Jobviz\Agent\JobvizAgent;
use Jobviz\Agent\Providers\LaravelQueueProvider;
use Jobviz\Agent\Providers\MultiProvider;
// Monitor multiple queue backends in a single agent
$agent = new JobvizAgent(
apiKey: config('jobviz.api_key'),
provider: new MultiProvider([
// Laravel Queues (Redis connection)
new LaravelQueueProvider(
queues: ['emails', 'reports'],
connection: 'redis',
),
// Your custom provider
new CronJobProvider([
['name' => 'sync-analytics', 'cron' => '*/5 * * * *', 'handler' => fn () => syncAnalytics()],
['name' => 'cleanup-sessions', 'cron' => '0 * * * *', 'handler' => fn () => cleanupSessions()],
]),
]),
);
$agent->trackDeployment([
'version' => '2.0.0',
'commitHash' => 'abc123f',
]);
$agent->start();
// Graceful shutdown
register_shutdown_function(fn () => $agent->stop()); Tip: You can mix
LaravelQueueProvider,
SymfonyMessengerProvider,
and custom providers in the same MultiProvider.