pusher/pusher-php-server
PHP server library for Pusher Channels HTTP API. Send events, trigger broadcasts, authenticate private/presence channels, and manage webhooks/requests from your PHP app. Supports PHP 7.3–8.4 and integrates with Laravel broadcasting.
Installation:
composer require pusher/pusher-php-server
Add to composer.json if preferred:
"require": {
"pusher/pusher-php-server": "^7.2"
}
Initialize Pusher Client:
use Pusher\Pusher;
$pusher = new Pusher(
env('PUSHER_APP_KEY'),
env('PUSHER_APP_SECRET'),
env('PUSHER_APP_ID'),
['cluster' => env('PUSHER_APP_CLUSTER')]
);
First Use Case: Trigger an event to a channel:
$pusher->trigger('notifications', 'new-message', ['content' => 'Hello World']);
Event Triggering:
$pusher->trigger('channel-name', 'event-name', ['data' => 'value']);
$pusher->trigger(['channel-1', 'channel-2'], 'event-name', ['data' => 'value']);
$batch = [
['channel' => 'channel-1', 'name' => 'event-1', 'data' => ['key' => 'value']],
['channel' => 'channel-2', 'name' => 'event-2', 'data' => ['key' => 'value']],
];
$pusher->triggerBatch($batch);
Authentication:
$pusher->authorizeChannel('private-channel', $socketId);
$pusher->authorizePresenceChannel('presence-channel', $socketId, $userId, ['user_data']);
$pusher->authenticateUser($socketId, $userId);
Channel Management:
$info = $pusher->getChannelInfo('channel-name', ['info' => 'subscription_count,user_count']);
$channels = $pusher->getChannels(['filter_by_prefix' => 'private-']);
Webhooks:
$webhook = $pusher->webhook($requestHeaders, $requestBody);
foreach ($webhook->get_events() as $event) {
// Process event
}
Asynchronous Operations:
triggerAsync/triggerBatchAsync for non-blocking calls:
$promise = $pusher->triggerAsync('channel', 'event', ['data']);
$promise->then(function($result) { /* Handle result */ });
// config/broadcasting.php
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => ['cluster' => env('PUSHER_APP_CLUSTER')],
],
Broadcasts trait to events:
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class NewMessage implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public function broadcastOn()
{
return new Channel('notifications');
}
}
Encryption Limitations:
private-encrypted-) and unencrypted channels in a single trigger call fails. Use separate calls or batches.encryption_master_key_base64 is 32 bytes (base64-encoded). Generate it securely:
openssl rand -base64 32
Async Operations:
triggerAsync returns a Guzzle Promise. Always handle it with .then() or .wait() to avoid silent failures.$pusher->triggerAsync('channel', 'event', ['data'])
->then(function($result) {
// Success
})
->otherwise(function($error) {
// Error handling
});
Webhook Validation:
try {
$webhook = $pusher->webhook($headers, $body);
} catch (\Pusher\Exceptions\WebhookException $e) {
// Handle invalid signature
}
Rate Limiting:
// Instead of:
$pusher->trigger('channel', 'event1', ['data']);
$pusher->trigger('channel', 'event2', ['data']);
// Use:
$pusher->triggerBatch([
['channel' => 'channel', 'name' => 'event1', 'data' => ['data']],
['channel' => 'channel', 'name' => 'event2', 'data' => ['data']],
]);
Socket ID Handling:
socket_id in trigger sends events to all subscribers. Include it to exclude the sender:
$pusher->trigger('channel', 'event', ['data'], ['socket_id' => $socketId]);
Cluster Configuration:
cluster in options (e.g., 'cluster' => 'mt1'). Defaults to us2 if omitted, which may cause misrouting.Logging:
$logger = new Monolog\Logger('pusher');
$pusher->setLogger($logger);
DEBUG for verbose output.HTTP Errors:
try {
$pusher->trigger('channel', 'event', ['data']);
} catch (\Pusher\Exceptions\PusherException $e) {
\Log::error('Pusher error: ' . $e->getMessage());
}
Channel Info Quirks:
getChannelInfo may return null for non-existent channels. Always check:
$info = $pusher->getChannelInfo('nonexistent-channel');
if (!$info) {
// Handle error
}
Environment Variables:
.env or a similar system for credentials. Never hardcode:
PUSHER_APP_KEY=your_key
PUSHER_APP_SECRET=your_secret
PUSHER_APP_ID=your_app_id
PUSHER_APP_CLUSTER=your_cluster
Custom Guzzle Client:
$client = new GuzzleHttp\Client([
'timeout' => 10,
'headers' => ['User-Agent' => 'MyApp/1.0'],
]);
$pusher = new Pusher($key, $secret, $appId, [], $client);
Event Data Transformation:
$data = ['original' => 'data'];
$processedData = json_encode($data); // Or any transformation
$pusher->trigger('channel', 'event', $processedData, [], true); // true = already JSON
Presence Channel Data:
$userData = ['name' => auth()->user()->name, 'role' => auth()->user()->role];
$p
How can I help you explore Laravel packages today?