メインコンテンツへスキップ
パッケージがリアルタイムイベントを配信するときは、チャンネル名の定義と利用者を通す判定を分けて設計します。パッケージの boot() で登録したチャンネルは、利用アプリの routes/channels.php と同じ名前だと上書きされることがあります。この登録順と評価順を理解しておくと、保守時の不具合を減らせます。 このページは、Laravel公式ドキュメントのブロードキャストと、確認に使った最新リリース v13.42.0 の実装を参照しています。イベントの送信方法はブロードキャスト、プロバイダーの読み込みはパッケージ自動検出を参照してください。

チャンネル認可の仕組み

プライベートチャンネルを購読すると、クライアントは /broadcasting/auth にリクエストを送ります。BroadcastController::authenticate() は Broadcast::auth() に処理を渡し、Broadcaster が登録済みのコールバックを順番に評価します。 評価の規則は次のとおりです。
  • コールバックが false を返すと、その時点で AccessDeniedHttpException が投げられます。
  • true などの真の値を返すと、その時点で認可が成立します。
  • null などの偽の値を返すと、次に登録されたコールバックへ進みます。どれも通さなければ、最後に AccessDeniedHttpException が投げられます。
Pusher と Reverb のドライバーは、認可の前に private- や presence- の接頭辞を取り除きます。そのため、登録するチャンネル名には接頭辞を含めません。

パッケージでチャンネルを登録する

例として、架空の Acme\Orders パッケージで注文の状態変化を配信します。チャンネル名は acme.orders.{order} とし、注文の所有者だけが購読できるようにします。 パッケージの ServiceProvider では、boot() の中で Broadcast::channel() を呼び出します。判定はパッケージ内のクラスに委譲します。
join() の第1引数には、認可時のユーザーが渡されます。以降の引数は、チャンネル名の {...} の値です。{order} のパラメーター名と Order $order の型が一致し、型が UrlRoutable のサブクラスであれば、ルートモデルのバインディングが働きます。
Broadcast::channel() の $callback には、callable か join() メソッドを持つクラス名を指定できます。クラス名の場合は、Broadcaster::normalizeChannelHandlerToCallable() がコンテナで生成してから join() を呼びます。

利用アプリによる上書き

利用アプリの withBroadcasting() に渡したファイル(通常は routes/channels.php)は、withBroadcasting() が登録する booted コールバックの中で読み込まれます。booted コールバックは、すべてのサービスプロバイダーの boot() が終わったあとに実行されるため、パッケージの boot() の登録は先に行われます。 Broadcaster::channel() は、チャンネル名をキーにして内部の配列に保存します。そのため、利用アプリが同じ名前を登録すると、2番目の登録がパッケージの登録を置き換えます。Laravelは同名の登録を重複としてエラーにしません。 上書きを防ぐには、チャンネル名を一意にします。例えば acme.orders.{order} のように、パッケージ固有の接頭辞を付けると、利用アプリが同じ名前を登録する可能性が下がります。 チャンネル名はクライアントとの公開された契約です。一度決めたら変更しないでください。変更すると、古いクライアントが購読できなくなります。
同名のチャンネルは、後から登録したものが黙って優先されます。php artisan channel:list では、チャンネル名と解決先(クラス名または Closure)が表示されるため、どの登録が残っているかを確認できます。

チャンネルのオプションとガード

Broadcast::channel() の第3引数 $options は、チャンネルごとの設定として保存されます。guards を指定すると、認証に使うガードを順に試します。
guards を省略すると、リクエストの既定のユーザー($request->user())を認可に使います。guards を指定すると、先頭から順に $request->user($guard) を呼び、最初に得られたユーザーを使います。パッケージ側でガード名を固定せず、設定値として公開すると、利用アプリが選べます。

テストでチャンネルの登録を確認する

登録されたチャンネルは、ドライバーの getChannels() で Collection として取得できます。キーはチャンネル名そのものです。
認可の結果は、/broadcasting/auth へのHTTPテストで確認します。null と log のドライバーは auth() が何も返さないため、このテストには使えません。チャンネルはアプリの起動時に既定のドライバーへ登録されるため、テスト用の phpunit.xml などで BROADCAST_CONNECTION を reverb や pusher に設定してから、認証付きのリクエストを送ります。
テストアプリで /broadcasting/auth が登録されている必要があります。このルートは Broadcast::routes() が登録し、BroadcastManager::channelRoutes() は同じ処理を routes() に任せるだけです。ルートがキャッシュされている場合、routes() は何もしません。

保守時の注意

  • チャンネル名は公開された契約です。名前を変更すると、既存のクライアントが購読できなくなります。
  • クラスベースのチャンネルは、Container で解決されます。コンストラクターの依存は、コンテナで解決できる型にしてください。

まとめ

パッケージのチャンネル認可は、boot() で Broadcast::channel() を登録すれば動きます。利用アプリの routes/channels.php が同じ名前を後から登録すると、パッケージの認可は置き換えられます。チャンネル名に接頭辞を付け、判定をクラスに分け、HTTPテストで /broadcasting/auth の結果を確認すると、保守しやすくなります。

参照した一次情報

最終更新日 2026年11月14日