こんにちは、{{ Auth::user()->name }} さん
ログアウト @endauth @guest ログイン 新規登録 @endguest ``` ## ルートの保護 ログイン済みのユーザーだけがアクセスできるルートを作るには、`auth` ミドルウェアを使います。 ```php theme={null} // routes/web.php // 認証済みユーザーのみアクセス可能 Route::get('/dashboard', function () { return view('dashboard'); })->middleware('auth'); ``` 未認証のユーザーがアクセスしようとすると、自動的に `/login` にリダイレクトされます。 複数のルートをまとめて保護するにはグループを使います。 ```php theme={null} Route::middleware('auth')->group(function () { Route::get('/dashboard', [DashboardController::class, 'index']); Route::get('/profile', [ProfileController::class, 'show']); Route::get('/settings', [SettingsController::class, 'index']); }); ```この投稿を編集する権限がありません。
@endcannot ``` ## ポリシー(Policies) ポリシーは特定のモデルに関連する認可ロジックをクラスにまとめたものです。`Post` モデルに対する作成・閲覧・編集・削除の権限管理には、ゲートよりもポリシーが適しています。 ### Policyによる認可フロー ```mermaid theme={null} flowchart TD A["HTTPリクエスト"] --> B["コントローラー"] B --> C["Gate::authorize('update', $post)"] C --> D{"PostPolicy::before(){{ $post->body }}
投稿者: {{ $post->user->name }}
@can('update', $post) 編集 @endcan @can('delete', $post) @endcan ```ユーザー: {{ $user->name }}
@endforeach @forelse ($users as $user)ユーザーがいません
@endforelse @while (true)永久にループします。
@endwhile ``` ループ内では `@break` と `@continue` を使ってループを制御できます。 ```blade theme={null} @foreach ($users as $user) @if ($user->type == 1) @continue @endifユーザー: {{ $user->name }}
@endforeach ``` | プロパティ | 説明 | | - | - | | `$loop->index` | 現在のループインデックス(0始まり) | | `$loop->iteration` | 現在のループ反復回数(1始まり) | | `$loop->remaining` | 残りの反復回数 | | `$loop->count` | 配列の要素数 | | `$loop->first` | 最初の繰り返しか | | `$loop->last` | 最後の繰り返しか | | `$loop->even` | 偶数番目の繰り返しか | | `$loop->odd` | 奇数番目の繰り返しか | | `$loop->depth` | 現在のループのネスト深度 | | `$loop->parent` | ネストしたループの場合、親ループの変数 | ## コメント Bladeコメントはレンダリングされたページに含まれません。 ```blade theme={null} {{-- このコメントはレンダリングされたHTMLに含まれません --}} ``` ## レイアウト ### コンポーネントを使ったレイアウト Laravelのレイアウト構築には、Bladeコンポーネントを使う方法が推奨されます。 まずレイアウトコンポーネントを作成します。 ```blade theme={null}ようこそ!
サイドバーに追加されるコンテンツ
@endsection @section('content')コンテンツ本体
@endsection ```{{ $user->name }}
@endforeach{{ $user->name }}
@endforeach {{ $users->links() }} ``` `paginate()` の結果をビューに渡し、`links()` でページリンクを出力するだけです。 現在のページは `page` クエリパラメーターから自動で検出されます。{{ $post->body }}
追跡番号: {{ $trackingCode }}
``` ビューの名前空間はComposerのパッケージ名やPHPの名前空間とは別です。ここでは `loadViewsFrom()` の第2引数に指定した `courier` が、ビュー参照と上書き先ディレクトリの契約になります。 ## ファイル単位で上書き先を探す `ServiceProvider::loadViewsFrom()` は `view` が解決されたときに、設定の `view.paths` を順番に確認します。各パスに `vendor/courier` ディレクトリが存在する場合は、そのディレクトリを名前空間へ追加し、最後にパッケージ側のパスを追加します。 `FileViewFinder` は、その名前空間のパスを順番に検索し、最初に見つかったファイルを返します。標準の `resources/views` を使う構成では、次の順序です。 ```mermaid theme={null} flowchart TD A["courier::deliveries.show"] --> B["resources/views/vendor/courier/{{ $exception->getMessage() }}
トップページへ戻る ``` ### デフォルトのエラーテンプレートを公開する Laravel 標準のエラーページをカスタマイズの出発点として使いたい場合は `vendor:publish` で取得します。 ```shell theme={null} php artisan vendor:publish --tag=laravel-errors ``` ### フォールバックエラーページ 特定のステータスコードに対応するビューがない場合のフォールバックとして、`4xx.blade.php` と `5xx.blade.php` を作成できます。 ``` resources/ └── views/ └── errors/ ├── 4xx.blade.php # 400番台のフォールバック └── 5xx.blade.php # 500番台のフォールバック ```{{ __('messages.welcome', ['name' => $user->name]) }}
``` ## 複数形 言語によって複数形のルールが異なります。Laravelは `|` 記号で単数形と複数形を切り替えられます。 ### 基本的な複数形 ```php theme={null} // lang/ja/messages.php return [ 'apples' => 'りんごが1個あります|りんごが複数あります', ]; ``` JSON形式でも同様に定義できます。 ```json theme={null} { "There is one apple|There are many apples": "りんごが1個あります|りんごが複数あります" } ``` `trans_choice()` 関数で数量を渡して取得します。 ```php theme={null} echo trans_choice('messages.apples', 1); // => りんごが1個あります echo trans_choice('messages.apples', 5); // => りんごが複数あります ``` ### 範囲を指定した複数形 より詳細な範囲指定ができます。 ```php theme={null} 'apples' => '{0} りんごはありません|[1,19] いくつかのりんごがあります|[20,*] たくさんのりんごがあります', ``` ```php theme={null} echo trans_choice('messages.apples', 0); // => りんごはありません echo trans_choice('messages.apples', 10); // => いくつかのりんごがあります echo trans_choice('messages.apples', 50); // => たくさんのりんごがあります ``` ### 複数形でのプレースホルダー `:count` で数量を表示できます。第3引数に追加の置換値を渡せます。 ```php theme={null} // lang/ja/messages.php return [ 'minutes_ago' => '{1} :value分前|[2,*] :value分前', 'items' => ':count件のアイテムがあります', ]; ``` ```php theme={null} echo trans_choice('messages.minutes_ago', 5, ['value' => 5]); // => 5分前 echo trans_choice('messages.items', 3); // => 3件のアイテムがあります ``` ## パッケージの言語ファイルをオーバーライド サードパーティパッケージが独自の言語ファイルを持っている場合、`lang/vendor/{パッケージ名}/{言語コード}/` に同名ファイルを置くことで上書きできます。 たとえば `skyrim/hearthfire` パッケージの英語メッセージをカスタマイズするには。 ```text theme={null} lang/ └── vendor/ └── hearthfire/ └── en/ └── messages.php ``` ```php theme={null} // lang/vendor/hearthfire/en/messages.php return [ 'welcome' => 'カスタマイズしたメッセージ', // 上書きしたいキーだけ定義する。他のキーは元のファイルから読み込まれる ]; ``` ## 実践例: 日英切り替えミドルウェア URLパスやセッション、ユーザー設定に基づいてロケールを自動切り替えするミドルウェアの実装例です。注文番号: {{ $order->id }}
合計金額: ¥{{ number_format($order->total) }}
ご注文いただきありがとうございました。
``` データを `with` パラメーターで明示的に渡すこともできます。この場合はプロパティを `protected` または `private` にします。 ```php theme={null} public function __construct( protected Order $order, ) {} public function content(): Content { return new Content( view: 'mail.orders.shipped', with: [ 'orderId' => $this->order->id, 'total' => $this->order->total, ], ); } ``` ## メールの送信 `Mail` ファサードの `to()` メソッドで宛先を指定し、`send()` でメールを送信します。 ```mermaid theme={null} flowchart TD A["Mail::to()->send(new OrderShipped())"] --> B{"ShouldQueue
```
## まとめ
| やりたいこと | 方法 |
| - | - |
| 開発サーバーを起動する | `npm run dev` |
| 本番用アセットをビルドする | `npm run build` |
| Bladeでアセットを読み込む | `@vite(['resources/css/app.css', 'resources/js/app.js'])` |
| Bladeビュー変更で自動リロード | `refresh: true` を `vite.config.js` に設定 |
| Tailwind CSSを使う | `@tailwindcss/vite` プラグインを追加 |
| `@` エイリアスを使う | デフォルトで `resources/js` を指す |
| 静的アセットをバージョニングする | `assets` オプションと `Vite::asset()` を使う |
## 次のステップ
` | PHPコードを直接実行 |
| `cpx exec ` | GitHub Gistをダウンロードして実行 |
| `cpx tinker` | インタラクティブREPLを開く |
Laravelプロジェクト内では `cpx exec` がconfig・facade・`.env`を含めてフルにアプリケーションをブート(`$app`が使用可能)し、`cpx tinker` はプロジェクト自身の `php artisan tinker` を実行します(`laravel/tinker`がインストールされている場合)。それ以外の場所ではPsySHシェルが起動します。
スクリプト内では `cpx_require('vendor/package')`(1.xの`composer_require()`から改名)でパッケージをその場でオートロードできます。
### エイリアス機能
長いパッケージ名を覚えなくて済むよう、独自のショートカットを定義できます。
```bash theme={null}
cpx alias laravel/pint pint
cpx aliases # 定義済みエイリアスの一覧
cpx unalias pint # エイリアスの削除
```
1.xに組み込まれていたポピュラーパッケージ向けのビルトインエイリアス一覧は廃止されたため、必要なら自分で定義する必要があります。
### 非対話モードとJSON出力
cpxは[laravel/agent-detector](https://github.com/laravel/agent-detector)によるAIエージェント検出、標準入力のリダイレクト、`--no-interaction`/`-n` フラグから非対話環境を自動検出します。非対話モードでは、`installed`・`aliases`・`alias`・`unalias`・`clean`・`update` などcpx自身の管理コマンドが整形テキストの代わりに1行のJSONを返します。対話端末からでも `--json` を渡せば同じ出力を得られます。
## v1.xからの主な変更点(コマンド)
| 1.x | 2.x |
| - | - |
| `cpx list`(インストール済み一覧) | `cpx installed` に変更(`list`はコマンド一覧を表示) |
| ビルトインのエイリアス一覧 | 廃止。`cpx alias`で自分で定義 |
| `cpx check` / `cpx format` / `cpx test` | 廃止。`cpx pint`・`cpx phpstan`・`cpx pest`など直接実行 |
| `cpx version` / `-v` | 廃止。`cpx --version`を使用 |
| `cpx script.php`(ファイル直接実行) | 廃止。`cpx exec script.php`が必要 |
| `composer_require()` | `cpx_require()`に改名 |
## 関連ページ
`~/.cpx`ディレクトリのキャッシュや旧バージョンパッケージは自動的に新形式へ移行されますが、バージョン制約付きで実行していたパッケージは新しいディレクトリ名で管理されるため初回のみ再インストールされます。不要になった1.x時代のコピーは `cpx clean` で削除できます。
ソースコードと最新のREADMEはこちら。
1.xから2.xへの詳細な移行手順。
# Inertia.jsでSPAを構築する
Source: https://kawax.biz/jp/blog/inertia-introduction
LaravelバックエンドとVue/React/SvelteフロントエンドをつなぐInertia.js v3を紹介します。APIなしでSPAを実現する仕組みから、ページコンポーネント・共有データ・フォーム処理まで実践的に解説します。
## Inertia.jsとは
フロントエンドをReactやVueで作りたい。でもAPIを別途設計・実装・管理するのは避けたい——そんなジレンマを解決するのが **Inertia.js** です。
Inertia はサーバーサイドのルーティングとコントローラーをそのままに、フロントエンドだけをReact・Vue・Svelteで書けるようにする「グルー(接着剤)」です。フレームワークではなく、既存のLaravelとJavaScriptフレームワークをつなぐアダプター層として機能します。
現在の最新バージョンはInertia v3(2026年3月26日リリース)です。Laravel 13のスターターキット(React・Vue・Svelte)はInertia対応済みです。
### 従来のSPA・MPAとの違い
| アーキテクチャ | 特徴 | 課題 |
| - | - | - |
| MPA(従来のBladeアプリ) | シンプル、Laravelとの統合が容易 | ページ遷移のたびにフルリロード |
| SPA(API + フロントエンド分離) | 高いインタラクション性 | API設計・認証・型定義の二重管理 |
| **Inertia(モダンモノリス)** | SPAのUX + サーバー側のシンプルさ | 独自の学習コストがある |
Inertia を使うと、Laravelのコントローラーから直接VueコンポーネントやReactコンポーネントにデータを渡せます。REST APIを定義する必要はなく、ページ遷移もブラウザのフルリロードではなくXHRで行われるため、SPA的なスムーズな操作感を実現できます。
***
## Laravelスターターキットとの関係
`laravel new` でプロジェクトを作成する際にReact・Vue・Svelteを選ぶと、Inertiaが自動的にセットアップされます。
```shell theme={null}
laravel new my-app
# 対話式プロンプトでReact / Vue / Svelteを選ぶとInertia構成になる
```
スターターキットでは以下の構成が自動で用意されます。
* `inertiajs/inertia-laravel`(サーバーサイドアダプター)
* `@inertiajs/react` / `@inertiajs/vue3` / `@inertiajs/svelte`(クライアントアダプター)
* `HandleInertiaRequests` ミドルウェア
* ログイン・登録・パスワードリセットなどの認証画面(すでにInertiaコンポーネントで実装済み)
既存プロジェクトに手動でInertiaを導入する場合はサーバーサイドとクライアントサイドを別々にインストールします。詳細は公式ドキュメントのインストール手順を参照してください。
***
## `Inertia::render()` の基本
Laravelのコントローラーから Inertia レスポンスを返すには `Inertia::render()` を使います。第一引数にJavaScriptコンポーネント名、第二引数にプロップとして渡すデータを指定します。
```php theme={null}
use Inertia\Inertia;
class PostController extends Controller
{
public function index()
{
return Inertia::render('Posts/Index', [
'posts' => Post::latest()->paginate(10),
]);
}
public function show(Post $post)
{
return Inertia::render('Posts/Show', [
'post' => $post->only('id', 'title', 'content', 'created_at'),
'author' => $post->user->only('id', 'name'),
]);
}
}
```
`Inertia::render()` の代わりに `inertia()` ヘルパー関数も使えます。どちらを使うかはチームのスタイルで統一してください。
コンポーネント名 `'Posts/Index'` はファイルパスに対応します。Reactなら `resources/js/Pages/Posts/Index.jsx`、Vueなら `resources/js/Pages/Posts/Index.vue` が対応するコンポーネントです。
***
## ページコンポーネントの構造
Inertiaのページコンポーネントは通常のVue/Reactコンポーネントです。コントローラーから渡したデータがプロップとして受け取れます。
```jsx React theme={null}
// resources/js/Pages/Posts/Index.jsx
import { Link } from '@inertiajs/react'
export default function PostsIndex({ posts }) {
return (
投稿一覧
{posts.data.map(post => (
{post.title}
))}
)
}
```
```vue Vue theme={null}
投稿一覧
{{ post.title }}
```
`` コンポーネントを使うと、ページ遷移がXHRで行われ、フルページリロードを回避できます。通常の `` タグとまったく同じように書けますが、裏側でInertiaがページコンポーネントだけを差し替えます。
***
## 共有データ — `HandleInertiaRequests` ミドルウェア
すべてのページで共通して必要なデータ(ログイン中のユーザー情報・フラッシュメッセージなど)は、`HandleInertiaRequests` ミドルウェアの `share()` メソッドで定義します。
```php theme={null}
// app/Http/Middleware/HandleInertiaRequests.php
use Illuminate\Http\Request;
use Inertia\Middleware;
class HandleInertiaRequests extends Middleware
{
public function share(Request $request): array
{
return array_merge(parent::share($request), [
'appName' => config('app.name'),
'auth' => [
'user' => $request->user()
? $request->user()->only('id', 'name', 'email')
: null,
],
'flash' => [
'success' => $request->session()->get('success'),
'error' => $request->session()->get('error'),
],
]);
}
}
```
共有データは自動的にすべてのページのプロップにマージされます。
```jsx React theme={null}
// レイアウトコンポーネントからアクセスする例
import { usePage } from '@inertiajs/react'
export default function Layout({ children }) {
const { auth, flash } = usePage().props
return (
{auth.user ? `ログイン中: ${auth.user.name}` : 'ゲスト'}
{flash.success && {flash.success}}
{children}
)
}
```
共有データはすべてのリクエストに含まれるため、必要最低限のデータに絞ることを推奨します。`fn()` を使ったレイジー評価にすると、実際に必要なリクエストでのみ評価されます。
***
## フォーム送信とバリデーションエラーの処理
Inertiaでのフォーム処理はLaravelのバリデーションと自然に統合されます。`useForm()` ヘルパーを使うと、フォームの状態管理・送信・エラー表示がシンプルに実装できます。
### コントローラー側
```php theme={null}
class PostController extends Controller
{
public function store(Request $request)
{
$validated = $request->validate([
'title' => ['required', 'string', 'max:255'],
'content' => ['required', 'string'],
]);
Post::create($validated + ['user_id' => auth()->id()]);
return redirect()->route('posts.index')
->with('success', '投稿を作成しました。');
}
}
```
バリデーションエラーが発生した場合、Laravelは自動的にフォームページにリダイレクトし、エラー情報をセッションに保存します。Inertiaはこれを自動的に検知して `errors` プロップとしてページに渡します。
### フロントエンド側
```jsx React theme={null}
// resources/js/Pages/Posts/Create.jsx
import { useForm } from '@inertiajs/react'
export default function PostsCreate() {
const { data, setData, post, processing, errors } = useForm({
title: '',
content: '',
})
function handleSubmit(e) {
e.preventDefault()
post('/posts')
}
return (
)
}
```
```vue Vue theme={null}
```
バリデーションエラーが返ったとき、`useForm()` は入力内容を保持したままエラーを表示します。フォームを再入力させる手間がなく、ユーザー体験が向上します。
***
## 向いているユースケース・向いていないケース
### Inertiaが向いているケース
* Laravelをよく知っているチームがSPA的なUIを作りたいとき
* 認証・認可・バリデーションをLaravel側で一元管理したいとき
* 管理画面・社内ツールなど、SEOの優先度が低いアプリ
* APIを別途設計・管理するコストを避けたいプロジェクト
### 向いていないケース
* 外部の複数クライアント(モバイルアプリなど)が同じAPIを使う場合
* SEOが非常に重要なコンテンツサイト(SSRで対応可能だが複雑になる)
* マイクロフロントエンド構成など、フロントエンドが完全に独立したチームで開発される場合
Inertia はサーバーサイドレンダリング(SSR)もサポートしています。SEOが必要なページがある場合は SSR オプションを検討してください。Laravel のスターターキットでも SSR 設定が組み込まれています。
***
## Inertia v3 の主な変更点
Inertia v3 は2026年3月26日にリリースされました。v2からの主な変更点を紹介します。
### Axios を廃止 — 軽量な組み込みXHRクライアントへ
v3 では Axios が廃止され、より軽量な組み込みXHRクライアントに置き換えられました。ほとんどのアプリケーションでコード変更は不要です。Axios のインターセプターは組み込みインターセプターに直接移行できます。引き続き Axios を使いたい場合は Axios アダプター経由で利用できます。
### `@inertiajs/vite` プラグインによるSSRのシンプル化
新しい Vite プラグインを導入すると、ページコンポーネントの自動解決とSSR設定が大幅に簡略化されます。開発中のSSRは `npm run dev` を実行するだけで動作するようになり、別途Nodeサーバーを起動する必要がなくなりました。
```bash theme={null}
npm install @inertiajs/vite@^3.0
```
### `useHttp` フック — ページ遷移を伴わないHTTPリクエスト
`useHttp` フックを使うと、ページ遷移(Inertia visit)を発生させずにサーバーへHTTPリクエストを送れます。モーダルの保存やバックグラウンド処理など、現在のページを維持したまま通信したい場面で役立ちます。
### 楽観的UI更新(Optimistic Updates)
`useForm` およびルーターレベルで楽観的な更新がサポートされました。サーバーの応答を待たずにUIを即座に更新し、失敗した場合は自動的にロールバックします。
### レイアウトプロップ(Layout Props)
`useLayoutProps` フックを使うと、ページコンポーネントから永続レイアウトへデータを渡せるようになりました。従来は共有データかページプロップに頼るしかなかった「特定ページのレイアウト状態制御」がシンプルに書けます。
### 要件の変更
v3 では以下の最低バージョンが引き上げられました。
| 項目 | v2 | v3 |
| - | - | - |
| PHP | 8.1+ | 8.2+ |
| Laravel | 10+ | 11+ |
| React | 18+ | 19+ |
| Svelte | 4+ | 5+ |
### `Inertia::lazy()` の廃止
v2 で非推奨になっていた `Inertia::lazy()` が v3 で完全に削除されました。代わりに `Inertia::optional()` を使います。
```php theme={null}
// v2(非推奨)
'users' => Inertia::lazy(fn () => User::all()),
// v3
'users' => Inertia::optional(fn () => User::all()),
```
### イベント名の変更
| v2 | v3 |
| - | - |
| `invalid` | `httpException` |
| `exception` | `networkError` |
### `future` オプションの廃止
v2 で実験的オプションとして提供されていた `future` 設定ブロックが廃止されました。これらのオプションはすべてデフォルトで有効になっています。`createInertiaApp` の設定から `future` ブロックを削除してください。
v2 からのアップグレード手順の詳細は 公式アップグレードガイド を参照してください。v2 は2026年9月26日までバグ修正が、2027年3月26日までセキュリティ修正が提供されます。
***
## まとめ
Inertia.js は「LaravelはそのままでフロントエンドをReact/Vueで書きたい」という現実的なニーズに応えるツールです。APIを設計せずに、コントローラーから直接コンポーネントにデータを渡せるシンプルさが最大の強みです。
Laravel 13 のスターターキットが Inertia に対応していることからも、Laravel エコシステムにおける Inertia の位置づけは確立されています。Livewire がPHPだけで動的UIを作るアプローチなら、Inertia はJavaScriptフレームワークのパワーをサーバー側のシンプルさを損なわずに使えるアプローチです。
どちらを選ぶかはチームのスキルセットとプロジェクトの要件次第ですが、「LaravelのコントローラーをそのままにReactで画面を作りたい」という場面では Inertia が最も自然な選択です。
Inertia v3の全機能については公式ドキュメントを参照してください。
# Laravel 13 新機能まとめ
Source: https://kawax.biz/jp/blog/laravel-13-new-features
2026年3月にリリースされたLaravel 13の主要な新機能と改善点を解説します。
## はじめに
Laravel 13 は 2026年3月17日にリリースされました。毎年恒例のメジャーリリースですが、Laravel 13 は特に **AI ネイティブなワークフロー**、**より安全なデフォルト**、**より表現力豊かな開発者向け API** に焦点を当てています。
破壊的変更は最小限に抑えられており、ほとんどのアプリケーションは少ない修正でアップグレードできます。一方で、Laravel AI SDK やセマンティック検索など、モダンなアプリケーション開発を大きく変える新機能が多数追加されています。
Laravel 13 のサポートポリシー: バグフィックスは 2027年 Q3 まで、セキュリティフィックスは **2028年3月17日** まで提供されます。
***
## PHP 要件の更新
Laravel 13 では **PHP 8.3 以上** が必要です。PHP 8.2 のサポートは終了しています。
| バージョン | PHP | リリース日 | バグフィックス期限 | セキュリティフィックス期限 |
| - | - | - | - | - |
| 11 | 8.2 - 8.4 | 2024年3月12日 | 2025年9月3日 | 2026年3月12日 |
| 12 | 8.2 - 8.5 | 2025年2月24日 | 2026年8月13日 | 2027年2月24日 |
| **13** | **8.3 - 8.5** | **2026年3月17日** | **2027年 Q3** | **2028年3月17日** |
PHP 8.3 の主な恩恵として、型付き定数、`json_validate()` 関数、`#[\Override]` アトリビュートなどが利用できるようになります。
***
## 主要な新機能
### Laravel AI SDK
Laravel 13 の目玉機能は **ファーストパーティの AI SDK** です。テキスト生成、ツール呼び出しエージェント、埋め込み、音声、画像生成、ベクターストア統合を統一した API で提供します。
プロバイダーに依存しない形で AI 機能を構築しながら、Laravel らしい開発者体験を保てます。
**テキスト生成 (エージェント)**
```php theme={null}
use App\Ai\Agents\SalesCoach;
$response = SalesCoach::make()->prompt('このセールストランスクリプトを分析してください...');
return (string) $response;
```
**画像生成**
```php theme={null}
use Laravel\Ai\Image;
$image = Image::of('キッチンカウンターの上のドーナツ')->generate();
$rawContent = (string) $image;
```
**音声合成**
```php theme={null}
use Laravel\Ai\Audio;
$audio = Audio::of('Laravelでのコーディングが大好きです。')->generate();
$rawContent = (string) $audio;
```
**埋め込み生成**
```php theme={null}
use Illuminate\Support\Str;
$embeddings = Str::of('ナパバレーのワインは最高です。')->toEmbeddings();
```
詳細は [Laravel AI SDK ドキュメント](https://laravel.com/ai) を参照してください。
***
### セマンティック / ベクター検索
AI SDK と連携したネイティブなベクタークエリサポートが追加されました。PostgreSQL + `pgvector` を使ったセマンティック検索を、クエリビルダーから直接実行できます。
```php theme={null}
$documents = DB::table('documents')
->whereVectorSimilarTo('embedding', 'ナパバレーの最高のワイナリー')
->limit(10)
->get();
```
埋め込み列の追加からクエリまで、Laravel のエコシステム内で完結できます。
***
### JSON:API リソース
Laravel にファーストパーティの [JSON:API](https://jsonapi.org/) リソースサポートが追加されました。JSON:API 仕様に準拠したレスポンスを簡単に返せるようになります。
* リソースオブジェクトのシリアライゼーション
* リレーションシップのインクルード
* スパースフィールドセット
* リンク
* JSON:API 準拠のレスポンスヘッダー
***
### PHP アトリビュートの拡張
Laravel 13 は PHP アトリビュートによる宣言的な設定をフレームワーク全体に拡大しました。
**コントローラーへの適用**
```php theme={null}
withoutMiddleware([PreventRequestForgery::class]);
```
`VerifyCsrfToken` は非推奨のエイリアスとして残りますが、新しいクラス名への移行が推奨されます。
### キャッシュのデシリアライゼーション制限
`config/cache.php` に `serializable_classes` オプションが追加され、デフォルトは `false` です。これにより `APP_KEY` が漏洩した場合の PHP デシリアライゼーション攻撃を防ぎます。
```php theme={null}
// config/cache.php
'serializable_classes' => [
App\Data\CachedDashboardStats::class,
App\Support\CachedPricingSnapshot::class,
],
```
キャッシュに PHP オブジェクトを保存している場合は、明示的にクラスを許可リストに追加する必要があります。
***
## スターターキットの変更
Laravel 12 で刷新されたスターターキット(React/Vue/Livewire ベース)は Laravel 13 でも引き続き利用可能です。
Laravel 13 のリリース時期に合わせて **Inertia v3** もリリースされました。主な変更点:
* よりシンプルなレイアウト props
* Vite 8 サポート
* `withApp` コールバックの追加
* 新しい Blade コンポーネント
Inertia v3 を使用している場合は、合わせてアップグレードを検討してください。
***
## その他の改善点
### AI アシストアップグレード (Laravel Boost)
[Laravel Boost](https://github.com/laravel/boost) はファーストパーティの MCP サーバーです。Claude Code、Cursor、OpenCode、Gemini、VS Code などの AI エディターと連携して、`/upgrade-laravel-v13` スラッシュコマンドでアップグレードを半自動化できます。
```shell theme={null}
composer require laravel/boost:^2.0 --dev
```
### コントラクトの追加
以下のコントラクトに新しいメソッドが追加されました:
| コントラクト | 追加メソッド |
| - | - |
| `Bus\Dispatcher` | `dispatchAfterResponse` |
| `Routing\ResponseFactory` | `eventStream` (SSE サポート) |
| `Auth\MustVerifyEmail` | `markEmailAsUnverified` |
| `Queue\Queue` | `pendingSize`, `delayedSize`, `reservedSize`, `creationTimeOfOldestPendingJob` |
| `Cache\Store` / `Cache\Repository` | `touch` |
***
## まとめ
Laravel 13 は「少ない破壊的変更、多くの新機能」というリリースです。アップグレード作業は最小限で済む一方、特に **AI SDK** と **セマンティック検索** は現代のアプリケーション開発のあり方を変える可能性を持っています。
既存のアプリケーションを Laravel 12 から 13 へアップグレードする準備ができたら、詳細な手順は以下のガイドを参照してください。
破壊的変更の一覧と、ステップバイステップのアップグレード手順を解説しています。
# Laravel Cloud — Laravel専用PaaSの全貌
Source: https://kawax.biz/jp/blog/laravel-cloud
2025年に登場したLaravel Cloud。Forgeとの違い、得意なこと・苦手なこと、実際に使うメリットを解説する。
## Laravel Cloudとは
[Laravel Cloud](https://cloud.laravel.com/docs/intro) は、Laravel公式の**フルマネージドPaaS**です。\
アプリのデプロイ、スケーリング、データベース、キャッシュ、WebSocket基盤まで、Laravel向けに統合されています。
Cloudの[Changelog](https://cloud.laravel.com/docs/changelog)では、`February 24, 2025` に **Launched Laravel Cloud!** と記録されています。2025年に一般提供が始まった比較的新しいサービスです。
***
## Forgeとの違い
Laravel CloudとLaravel Forgeは、どちらもLaravel開発者向けですが、レイヤーが違います。
| 観点 | Laravel Cloud | Laravel Forge |
| - | - | - |
| 立ち位置 | フルマネージドPaaS | サーバー管理ツール |
| 主な操作 | 環境・リソースを選んでデプロイ | VPS / EC2 などをプロビジョニングして運用 |
| インフラ管理 | 最小限(Cloud側が管理) | OS・ミドルウェア運用の責任はユーザー側 |
| root権限 | なし(OSレベルの直接操作は想定しない) | あり(サーバー運用を柔軟に制御可能) |
「インフラを意識せずLaravelアプリを早く出す」ならCloud、\
「サーバーを細かく制御したい」ならForgeが向いています。
***
## Laravel Cloudが得意なこと
Laravel Cloudは、Laravelの実運用で使う機能をダッシュボード中心で有効化しやすい点が強みです。
### Task Scheduler
[Scheduled Tasks](https://cloud.laravel.com/docs/scheduled-tasks) で、AppクラスタまたはWorkerクラスタに **Scheduler** を有効化するだけで `schedule:run` が毎分実行されます。
### Managed Queues(マネージドキュー)
[Queues](https://cloud.laravel.com/docs/queues) では、**Managed Queues** が推奨されています。Laravel Cloud がキューのプロビジョニング、ワーカーの起動、スケーリングを自動で処理し、ジョブがない時はワーカー数がゼロまで下がるため、処理中だけ課金されます。
| 選択肢 | 向いている用途 | スケーリング | 料金の考え方 |
| - | - | - | - |
| **Managed Queues** | 本番・プレビュー・開発環境全般。まず最初に選ぶ構成 | キューの滞留状況に応じて自動。アイドル時はゼロまで縮退 | ワーカー稼働秒数 + キュー操作 |
| **Worker cluster** | `queue:work` を自前管理したい、大きめのバックグラウンド処理 | CPU / メモリベース | Worker cluster の通常料金 |
| **App cluster のバックグラウンドプロセス** | 小規模開発や低頻度ジョブ | CPU / メモリベース | App cluster に含まれる |
Managed Queues は、Webトラフィックとジョブ処理を分離しつつ、失敗ジョブのダッシュボードも使えます。\
一方で `database` や `redis` など別ドライバを自前管理したいなら Worker cluster、アプリと同じコンピュートで十分なら App cluster のバックグラウンドプロセスを使います。
環境のインフラキャンバスダッシュボードで **New Managed Queue** をクリックします。
キュー名、インスタンスサイズ、ポーリング間隔、最大ワーカー数などを設定します。
設定を保存して再デプロイすると、Laravel Cloud がキューとワーカープールを自動で用意します。
ジョブがない時は Managed Queues のワーカーがゼロまで下がるため、後述の Scale to Zero と組み合わせた構成と相性が良いです。App cluster 側を眠らせても、キュー処理だけ必要な時に自動で起動できます。
### Scale to Zero(Flex コンピュート)
[Compute](https://cloud.laravel.com/docs/compute#scale-to-zero) にある **Flex** は、低コストで柔軟に使える compute class です。新しい **Scale to Zero** は、この Flex コンピュートを旧 Hibernation から発展させた仕組みです。新しい **Flex コンピュート** では、HTTP リクエスト到着時の起動が **500ms 未満** まで短縮され、従来の 5〜20 秒待つ前提ではなくなりました。
有効化は App cluster の設定画面で **Scale to Zero** トグルをオンにし、保存後に再デプロイするだけです。
さらに、Scale to Zero が有効な環境では、スリープ中でも Scheduled Tasks とキュー処理のために環境が自動起動します。\
App cluster 上で `schedule:run` を回しつつ、ジョブ処理は Managed Queues に任せる構成が、現在の公式ドキュメントでも最も扱いやすい組み合わせです。
App cluster 上の自前 `queue:work` は sleep timeout をまたぐと中断される可能性があります。キュー処理を確実に続けたいなら、公式ドキュメント通り Managed Queues を優先してください。
### MySQL Scale to Zero
[Laravel MySQL](https://cloud.laravel.com/docs/resources/databases/laravel-mysql#scale-to-zero) の **Flex** サイズも Scale to Zero に対応しました。データベースが一定時間(1分〜1時間で設定可能なアイドルタイムアウト)接続を受け取らないとスリープし、コンピュート課金が止まります。ストレージは常時オンラインのままなので、スリープ中もデータは保持され、ストレージ分の課金のみ継続します。
次の接続が来ると自動的に起動します。すべての Laravel MySQL クラスタはプロキシ層でフロントされているため、起動中の接続はプロキシで保持されてからデータベースへ転送されます。接続エラーにはならず、最初のクエリが数百ミリ秒ほど遅くなる程度です(メモリサイズが大きいほど起動に時間がかかる傾向)。自動バックアップや手動スナップショットの際も一時的に起動し、完了後は再びスリープします。
現時点では US East (N. Virginia) と US East (Ohio) の Flex サイズで利用可能で、他リージョンは順次対応予定です。既存のデータベースは現在のサイズ・料金のまま変わらず稼働し続けます。**Pro** サイズは常時稼働で Scale to Zero の対象外です。
Scale to Zero 対応のFlexデータベースは、複数アプリで共有している、または1日中アクセスがあるデータベースではスリープしないため恩恵が薄くなります。既存のMySQLが安定して稼働しているなら、Scale to Zero対応版に変更すると最低料金がわずかに上がる($5.5 → $6.6)ケースもあるため、ワークロードに応じて判断してください。新規作成するMySQLはすでにScale to Zero対応版のみが選択肢になります。
[Compute の Scale to Zero](https://cloud.laravel.com/docs/compute#scale-to-zero)、[Laravel Valkey の Scale to Zero](https://cloud.laravel.com/docs/resources/caches/valkey#scale-to-zero) と組み合わせることで、開発環境やサイドプロジェクト、さらにはアクセスに波がある本番環境でもコストを最小化できます。
### Laravel Octane
[Compute](https://cloud.laravel.com/docs/compute#laravel-octane) の **Use Octane as runtime** を有効化すると、CloudがOctane + FrankenPHP構成で実行します。サーバー設定を手で組み立てる必要がありません。
### Inertia SSR
[Compute](https://cloud.laravel.com/docs/compute#inertia-ssr) の **Use Inertia SSR** を有効化して使えます。スターターキットを使う場合は `npm run build:ssr` が推奨されています。
### WebSocketサーバー(Reverb)
[Laravel Cloud WebSockets](https://cloud.laravel.com/docs/resources/websockets) で、ReverbベースのWebSocketクラスタを作成できます。環境にアタッチすると `REVERB_*` と `VITE_REVERB_*` が自動注入されます。
### Laravel Nightwatch連携
[Environments](https://cloud.laravel.com/docs/environments#nightwatch-integration) にはワンクリック連携があり、Cloudの[Changelog](https://cloud.laravel.com/docs/changelog)でも `July 1, 2025` に **One-Click Nightwatch Integration** が記録されています。\
手動構成が必要な場合も [nightwatch-on-cloud](https://cloud.laravel.com/docs/knowledge-base/nightwatch-on-cloud) に手順があります。
***
## 料金と無料プラン
Laravel Cloudの料金は、基本的に**プラン料金 + 使用量課金**です。\
詳細は常に [Pricing](https://cloud.laravel.com/docs/pricing) を確認してください。
* **Starter**: 月額 `$5`。毎月 `$5` 分の使用クレジット付き。新規サインアップは初月無料
* **Growth**: `$20/mo + usage`、毎月 `$5` 分の使用クレジット付き
* **Business**: `$200/mo + usage`、毎月 `$5` 分の使用クレジット付き
以前よりも **Starter** で小規模プロジェクトを始めやすくなりました。\
Scale to Zero と Managed Queues を組み合わせると、待機時間が長い個人開発や社内ツールでもコストを読みやすくなります。
***
## 実際に使う際の注意点
### root権限前提の運用はできない
CloudはPaaSなので、OSレベルの自由度より運用の簡便さを優先します。\
カーネル設定や独自デーモンの常駐など、root権限前提の作業が必要ならForgeなどの選択肢を検討します。
### Nightwatchのイベント量は最初に制御する
無料枠や小規模構成でNightwatchを使う場合、イベント量が増えやすいため最初にサンプリング調整を入れるのが安全です。
```ini theme={null}
NIGHTWATCH_REQUEST_SAMPLE_RATE=0.1
NIGHTWATCH_IGNORE_QUERIES=true
```
***
## 向いているプロジェクト・向いていないプロジェクト
### 向いている
* Laravelアプリを最短で本番投入したい
* Scheduler / Queue / Octane / Inertia SSR / Reverb をまとめて運用したい
* アプリ開発に集中し、サーバー運用コストを下げたい
### 向いていない
* root権限でOSレベルまで強くチューニングしたい
* 既存の特殊インフラ要件(独自ミドルウェアや特殊ネットワーク制約)が強い
***
## まとめ
Laravel Cloudは「Laravelの高度な機能を、インフラ構築の負担を下げて運用したい」チームに強く向いています。\
特に Scheduler / Queue / Octane / Inertia SSR / Reverb / Nightwatch を組み合わせるプロジェクトでは、立ち上げと運用の初速が大きく上がります。
一方で、root権限が必要な運用を前提にする場合はForgeのほうが適しています。\
まずは無料トライアルで実際のワークロードを流し、運用要件に合うかを確認するのが確実です。
# Laravel Cloud CLI — ターミナルからLaravel Cloudを操作する
Source: https://kawax.biz/jp/blog/laravel-cloud-cli
laravel/cloud-cliを使ってターミナルからLaravel Cloudのアプリ・環境・データベース・ドメインなどを管理する方法。
## Laravel Cloud CLIとは
`laravel/cloud-cli` は、[Laravel Cloud](https://cloud.laravel.com) をターミナルから操作するためのCLIです。\
このツールは Laravel Zero 製で、ダッシュボードで行う操作を `cloud` コマンドで実行できます。
あなたはこのCLIで、アプリケーション、環境、データベース、キャッシュ、バケット、ドメイン、WebSocketなどを一元管理できます。
## 要件
導入前に次の要件を満たしてください。
* `PHP 8.2+`
* `Composer`
* `GitHub CLI (gh)`(インストール済み、認証済み)
* `Git`
## インストール
まず、CLIをローカルにセットアップしてください。
```bash theme={null}
gh repo clone laravel/cloud-cli
cd cloud-cli
composer install
```
zsh:
```bash theme={null}
echo 'alias cloud="php '$(pwd)'/cloud"' >> ~/.zshrc
source ~/.zshrc
```
bash:
```bash theme={null}
echo 'alias cloud="php '$(pwd)'/cloud"' >> ~/.bashrc
source ~/.bashrc
```
```bash theme={null}
alias cloud="php /path/to/cloud-cli/cloud"
```
## 認証
多くのコマンドを使う前に認証してください。
```bash theme={null}
cloud auth
```
`cloud auth` はブラウザを開き、OAuthで認証します。\
CI用途などでトークンを管理したい場合は `cloud auth:token` を使います。
```bash theme={null}
cloud auth:token
```
## リポジトリ設定
あなたのプロジェクトで毎回 `application` や `environment` を選びたくない場合は、`cloud repo:config` を実行してください。
```bash theme={null}
cloud repo:config
```
この設定でGitリポジトリにデフォルト値が保存され、`cloud deploy` などを短いコマンドで実行できます。
## デプロイ
初回デプロイと継続デプロイを分けて使うと効率的です。
```bash theme={null}
# 初回: ガイド付きでアプリ作成とデプロイ
cloud ship
# 2回目以降: 既存アプリにデプロイ
cloud deploy
# ダッシュボードを開く
cloud dashboard
```
## 主なコマンドカテゴリ
READMEのコマンドリファレンスから、日常的に使うカテゴリをまとめます。
| カテゴリ | 主なコマンド例 | 用途 |
| - | - | - |
| Auth / Config | `cloud auth`, `cloud auth:token`, `cloud repo:config` | 認証とデフォルト設定 |
| Application | `cloud application:list`, `cloud application:create` | アプリ管理 |
| Environment | `cloud environment:list`, `cloud environment:get`, `cloud environment:logs` | 環境情報・ログ確認 |
| Deploy | `cloud ship`, `cloud deploy`, `cloud deploy:monitor` | デプロイ管理 |
| Database | `cloud database-cluster:*`, `cloud database:*`, `cloud database-snapshot:*` | DBクラスタ・DB・スナップショット管理 |
| Cache | `cloud cache:list`, `cloud cache:create`, `cloud cache:types` | キャッシュ管理 |
| Bucket | `cloud bucket:*`, `cloud bucket-key:*` | オブジェクトストレージ管理 |
| Domain | `cloud domain:list`, `cloud domain:create`, `cloud domain:verify` | ドメイン設定・検証 |
| WebSocket | `cloud websocket-cluster:*`, `cloud websocket-application:*` | Reverb関連リソース管理 |
## 環境変数管理
環境変数は `cloud environment:variables` で管理します。\
このコマンドは append / set / replace などの操作をまとめて扱えます。
```bash theme={null}
cloud environment:variables
```
CIやチーム運用では、このコマンドを使って設定変更の手順を統一してください。
## 使用量確認
課金やリソース利用状況は `cloud usage` で確認できます。
```bash theme={null}
# 当月の使用量
cloud usage
# 詳細表示
cloud usage --detailed
# 前期間の使用量
cloud usage --period=previous
```
環境単位で絞り込む場合は `cloud usage --environment=` を使ってください。
# Laravel Cloud Hibernation(自動休止)
Source: https://kawax.biz/jp/blog/laravel-cloud-hibernation
Laravel Cloudの自動休止機能の仕組み、有効化方法、制限事項、Path Blockingによる不要な復帰防止を解説します。
## Hibernation とは
Laravel Cloud の **Hibernation(自動休止)** は、一定時間 HTTP リクエストがない場合に環境を休止状態に移行する旧来の機能です。\
現在の新しい Flex コンピュートでは、より高速な **Scale to Zero** が後継として使われます。
Legacy Flex の Hibernation は、休止中のコンピュート課金を止められる一方で、HTTP リクエストを受けてからの復帰に通常 5〜20 秒かかります。新しい Scale to Zero では起動が **500ms 未満** まで短縮され、さらにスリープ中でもスケジュールタスクやキュー処理のために環境が自動で起動します。
新規に Laravel Cloud を使うなら、Hibernation ではなく **Scale to Zero** を前提に考えるのが安全です。Managed Queues や新しい料金プランも含めた全体像は [Laravel Cloud — Laravel専用PaaSの全貌](/jp/blog/laravel-cloud) を確認してください。
```mermaid theme={null}
sequenceDiagram
participant User as ユーザー
participant Cloud as Laravel Cloud
participant App as アプリ
User->>Cloud: リクエストなし(タイムアウト)
Cloud->>App: 休止状態へ移行
(課金停止)
User->>Cloud: HTTP リクエスト
Cloud->>App: 5〜20秒で復帰
App-->>User: レスポンス
```
## Scale to Zero で変わったこと
新しい Flex コンピュートの Scale to Zero では、以前の Hibernation で課題だった点がかなり解消されています。
| 項目 | 旧 Hibernation | 新しい Scale to Zero |
| - | - | - |
| HTTP リクエストでの復帰 | 5〜20 秒 | 500ms 未満 |
| Scheduled Tasks | 休止中は動かない | スリープ中でも自動起動して実行 |
| キュー処理 | 休止中は動かない | スリープ中でも自動起動。Managed Queues 併用が推奨 |
| 推奨用途 | 旧 Flex 環境の節約運用 | 現在の標準構成 |
以前の Hibernation では、休止中にタスクスケジュールやキューが動かない問題がありました。Scale to Zero ではこの問題が解消され、特にキュー処理は Managed Queues を使うと App cluster が眠っていても安全に継続できます。
## 旧 Hibernation の有効化手順
環境のインフラキャンバスダッシュボードで、App compute cluster をクリックします。
**Hibernation** トグルをオンにします。
**Save and Redeploy** をクリックして変更を反映します。
設定を変更しただけでは有効になりません。必ず Save and Redeploy が必要です。
現在の環境で新しく有効化するなら、App compute cluster の **Scale to Zero** トグルを使います。以下の制限事項は、主に旧 Hibernation / Legacy Flex を前提にした説明です。
## 旧 Hibernation 休止中の制限事項
Hibernation が有効で環境が休止している間は、以下の機能は動作しません。
| 機能 | 休止中の挙動 |
| - | - |
| HTTP リクエスト処理 | 停止(復帰後に処理) |
| Task Scheduler | 実行されない |
| Queue Worker | 実行されない |
| カスタムバックグラウンドプロセス | 実行されない |
休止から復帰すると、これらの処理は自動的に再開されます。ただし休止中に「来るべきだった」スケジュールのジョブが遡って実行されることはありません。
また、Hibernation には以下の制限があります。
* **Flex コンピュートのみ** 休止が可能です。Pro コンピュートでは Hibernation を有効にできません。
* 休止は**環境単位**で行われます。App cluster が休止すると、同環境内のすべての Worker cluster も休止します。
## 不要な復帰の原因
HTTP リクエストがあれば環境は自動で復帰しますが、意図しないリクエストによっても復帰が発生します。
* **ボット・クローラー** — 検索エンジンやセキュリティスキャナーなどが自動的にページをクロールする
* **Slack や Teams のリンクプレビュー** — メッセージングアプリがリンクのサムネイル取得のためにアクセスする
* **WordPress スキャン** — WordPress 環境を探す自動スキャンが `/wp-admin` などにアクセスする
* **`.php` ファイルを探す攻撃** — PHP ファイルを直接狙う自動スキャン
Laravel Cloud の `*.laravel.cloud` ドメインは検索エンジンにインデックスされないよう `X-Robots-Tag: noindex, nofollow` ヘッダーが付与されますが、ドメインが発見されてしまうと防ぎきれません。カスタムドメインでは `noindex` ヘッダーは付与されません。
なるべく複雑なドメイン名を使うことで、ボットにバニティドメインを発見されるリスクを減らせます。
## Path Blocking で不要な復帰を防ぐ
**Path Blocking** は、特定の拡張子やパスへのリクエストを休止状態のまま処理せずにブロックする機能です。WordPress スキャンや PHP ファイルを狙った攻撃リクエストによる不要な復帰を防ぎます。
デフォルトでブロックされる拡張子とパスは以下の通りです。
**ブロックされる拡張子:**
```
.php, .php3, .php4, .php5, .php6, .php7, .php8,
.phtml, .pht, .phps, .env, .git
```
**ブロックされるパス:**
```
/wp-admin, /wp-content, /wp-includes, /wp-json
```
これらのリクエストは、環境が休止中でもアプリを復帰させることなく応答を返します。
Laravel の通常のルーティングでは `.php` 拡張子付きのリクエストは使用しないため、これらをブロックしてもアプリの動作に影響はありません。
## 旧 Hibernation が向いているユース・不向きなユース
* **ステージング・開発環境** — 常時稼働は不要なのでコストを大幅に削減できる
* **個人ブログ・ポートフォリオ** — トラフィックが少なくて済む用途
* **デモ・試験用アプリ** — 必要なときだけ復帰すれば十分
* **低頻度の社内ツール** — 使用時間が限られている
* **タスクスケジュールを使う用途** — 休止中は `schedule:run` が実行されない
* **定期的なキュージョブが必要な用途** — 休止中はキューも停止する
* **起動レイテンシが許容できない本番環境** — 復帰に 5〜20 秒かかる
* **WebSocket を使うアプリ** — 接続が維持できず休止も遅延する場合がある
タスクスケジューラーで定期的に処理を実行したい場合(メール配信、データ集計など)は、Hibernation を有効にすると処理が実行されなくなります。このような用途では Hibernation をオフにするか、外部のスケジューラー(GitHub Actions など)からリクエストを送って環境を起こし続ける設計が必要です。
新しい Scale to Zero ではこの制約は緩和されています。Scheduled Tasks はスリープ中でも自動実行され、キュー処理も Managed Queues を使えば App cluster の休止に影響されません。
## まとめ
Hibernation は Legacy Flex では今でもコスト削減に使えますが、現在は Scale to Zero のほうが実用的です。
* Legacy Flex では稼働時間のみ課金。タイムアウト後に自動休止。
* 旧 Hibernation の復帰時間は 5〜20 秒。
* 新しい Scale to Zero は 500ms 未満で起動する。
* Scale to Zero では Scheduled Tasks と Managed Queues がスリープ中でも動作する。
* Path Blocking でボットによる不要な復帰を防ぐ。
* Flex コンピュートのみ対応。
## 関連ページ
Task Scheduler の設定と Laravel Cloud での動作を確認します。
Queue Worker の設定と Laravel Cloud での運用方法を確認します。
Managed Queues、Scale to Zero、新しい料金プランをまとめて確認します。
# Laravel Doctor — アプリケーション診断ツール
Source: https://kawax.biz/jp/blog/laravel-doctor-introduction
laravel/doctorの紹介。設定・環境・インフラの一般的な問題を診断し、安全なものは自動修正するLaravel公式パッケージ。php artisan doctorコマンドで実行。2026年7月28日リリース。
## はじめに
[laravel/doctor](https://github.com/laravel/doctor) は、Laravelアプリケーションにおける一般的な設定・環境・インフラストラクチャの問題を診断する公式パッケージです。2026年7月28日にv0.1.0がリリースされました。
それぞれの診断(diagnostic)は単一のチェックです。例えば「Laravelがstorageディレクトリに書き込めるか」を検査し、複数のステータスのいずれかを報告します。安全かつ決定的に修復できる場合は自動修正も提供され、アセットビルド失敗のように自動修復できない問題には対応手順(remediation)が提示されます。
```bash theme={null}
composer require laravel/doctor --dev
```
## 実行方法
インストール後、`doctor` Artisanコマンドが登録されます。
```bash theme={null}
php artisan doctor
```
修正可能な問題が見つかると、Doctorは問題を報告したうえで修正の確認を求めます。
```text theme={null}
Storage is writable: The application cannot write to every required storage directory.
Make the storage directories writable? (yes/no) [yes]
```
確認なしで修正を適用したい場合は `--fix` オプションを使います。
```bash theme={null}
php artisan doctor --fix
```
標準の修正は、`.env` の作成、`APP_KEY` の生成、本番環境でのデバッグモード無効化、`.env` の `.gitignore` 追加、`storage:link` の作成、storageディレクトリの書き込み権限修復など、決定的なローカル修復をカバーします。
修正機能はCLIとagent出力形式でのみ利用可能です。JSONおよびGitHubレポート形式では、機械可読なレポートがアプリケーションを変更しないよう`--fix`は拒否されます。
`--bail` を使うと、失敗またはエラーになった最初の診断で実行を停止します。
```bash theme={null}
php artisan doctor --bail
```
## 診断ステータス
各診断は次のいずれかのステータスを返します。
| ステータス | 意味 | 終了コードに影響 |
| - | - | - |
| `pass` | チェックに成功し問題なし | なし |
| `notice` | 開発者に伝える価値のある情報 | なし |
| `warn` | 対応が不要な場合もある潜在的な問題 | `--fail-on=warn` の場合のみ |
| `fail` | 解決すべき問題を検出 | あり |
| `skip` | 現在の環境には該当しない | なし |
| `error` | 診断の実行中に例外が発生 | あり |
デフォルトでは `fail` または `error` があると失敗ステータスで終了します。`--fail-on=warn` で警告でも失敗させたり、`--fail-on=never` で問題の報告のみに留めることもできます。
## 診断の選択
クラス名・グループ・パッケージ・パッケージのワイルドカードで診断を選択・除外できます。
```bash theme={null}
php artisan doctor --only=storage
php artisan doctor --only=StorageIsWritable
php artisan doctor --except=laravel/*
```
設定ファイルを公開すれば、永続的な選択設定も可能です。
```bash theme={null}
php artisan vendor:publish --tag=doctor-config
```
## 環境モード
`sync` キューはローカル開発では妥当なデフォルトですが、本番環境ではキュージョブがWebリクエスト内で同期実行されてしまうことを意味します。このような判断のため、Doctorはアプリケーションを `local` または `production` の2つのモードに解決します。
| モード | 期待される状態 |
| - | - |
| `local` | 開発中。デバッグモード、`sync` キュー、未キャッシュのbootstrapファイルは正常 |
| `production` | 実トラフィックを処理。デバッグモードはセキュリティリスク、キューは非同期実行、bootstrapファイルはキャッシュ済みであるべき |
Laravel標準の `local`・`production`・`staging` という環境名は自動認識されます。それ以外の名前を使う場合は設定ファイルでモードにグループ分けします。
```php theme={null}
'environments' => [
'local' => ['local', 'dev'],
'production' => ['production', 'staging', 'qa'],
],
```
## 標準診断
Doctorには以下を含む診断スイートが標準で搭載されています。
* **環境** — `.env` の存在、`APP_KEY`、PHPバージョン、必要な拡張機能、タイムゾーン
* **Composer** — 依存関係のインストール状態、オートロード最適化、`composer.lock` の自動修復
* **設定** — 設定ファイルの読み込み・キャッシュ可否、有効なドライバーが必要とする設定値
* **データベース** — 接続の到達性、SQLiteファイルの存在、保留中マイグレーションの自動適用
* **キャッシュ・キュー・スケジューラ・セッション** — 設定済みドライバーの到達性、本番環境外の `sync` キュー検出
* **ストレージ** — デフォルトディスクの到達性、必要ディレクトリの書き込み権限、`storage:link` の存在
* **セキュリティ** — デバッグモードと環境の整合性、`.env` の `.gitignore` 登録、Composer依存関係の監査
## 独自診断の作成
`Laravel\Doctor\Diagnostic` を継承し `check()` メソッドを実装するだけで独自の診断クラスを作成できます。`make:diagnostic` Artisanコマンドでスキャフォールドも可能です。
```bash theme={null}
php artisan make:diagnostic HorizonIsRunning --fixable
```
以下は `APP_KEY` の設定を確認し、未設定であれば自動生成する診断の例です。
```php theme={null}
namespace App\Doctor\Diagnostics;
use Illuminate\Support\Facades\Artisan;
use Laravel\Doctor\Contracts\Fixable;
use Laravel\Doctor\Diagnostic;
use Laravel\Doctor\EnvironmentMode;
use Laravel\Doctor\Results\DiagnosticResult;
use Laravel\Doctor\Results\FixResult;
class ApplicationKeyIsSet extends Diagnostic implements Fixable
{
public string $name = 'App key is set';
public string $group = 'environment';
protected function messages(): array
{
return [
'configured' => 'The application key is configured.',
'missing' => 'The application key is not configured.',
'generated' => 'The application key was generated.',
];
}
public function check(): DiagnosticResult
{
$key = config('app.key');
if (is_string($key) && trim($key) !== '') {
return $this->pass('configured');
}
return $this->fail('missing')->fixable(EnvironmentMode::Local);
}
public function fix(DiagnosticResult $result): FixResult
{
Artisan::call('key:generate', ['--force' => true]);
return $this->fixed('generated');
}
}
```
選択肢のある修正が妥当な場合は、`fixOptions()` で選択肢を宣言できます。CLIはこれを選択リストとして表示し、選ばれた値が `fix()` に渡されます。
```php theme={null}
return $this->fail('unreachable')
->fixable(EnvironmentMode::Local)
->fixOptions(['file' => 'File', 'redis' => 'Redis']);
```
選択リストの末尾には常に修正を見送る選択肢が追加されます(デフォルトは `Skip — leave unfixed`)。現在の選択を保つ表現の方が分かりやすい場合は `decline` ラベルを指定できます。
```php theme={null}
->fixOptions(['file' => 'File'], decline: 'Keep Redis (repair it manually)');
```
### 診断ヘルパー
多くのアプリケーションやパッケージは同じような種類のチェックを繰り返し書くことになるため、Doctorは `Laravel\Doctor\Support` 名前空間で頻出パターン向けのヘルパーを提供しています。
`Configured` ヘルパーは設定値を防御的に読み取ります。診断は設定が壊れたアプリケーションも報告前に例外を投げずに検査できる必要があるため、これらのメソッドは設定リポジトリの型付きアクセサとは違い、想定外の型でも例外を投げません。
```php theme={null}
use Laravel\Doctor\Support\Configured;
$connection = Configured::string('queue.default', 'database');
$missing = Configured::missing([
'services.stripe.key',
'services.stripe.secret',
]);
```
`ActiveDrivers` ヘルパーは、デフォルトのログチャンネルが `stack` であったりメーラーが `failover` であったりするラッパードライバーを、実際に使われている具体的なチャンネルやメーラーに解決します。
```php theme={null}
use Laravel\Doctor\Support\ActiveDrivers;
$channels = ActiveDrivers::logChannels(Configured::string('logging.default', 'stack'));
$mailers = ActiveDrivers::mailers(Configured::string('mail.default', 'log'));
```
`Details` ヘルパーは `withDetails()` に添付する証拠情報を整形します。`Details::bullets()` は文字列のリストを箇条書きに、`Details::failures()` はキー付き失敗メッセージを、`Details::processOutput()` は完了したプロセスから最も有用な出力ストリームを選択します。
```php theme={null}
use Laravel\Doctor\Support\Details;
Details::bullets(['services.stripe.key', 'services.stripe.secret']);
Details::failures(['media' => 'The disk root is not writable.']);
```
パッケージも同じAPIでサービスプロバイダーから診断を登録できます。
```php theme={null}
use Laravel\Doctor\Facades\Doctor;
use Vendor\Package\Diagnostics\HorizonIsRunning;
public function boot(): void
{
Doctor::diagnostic(HorizonIsRunning::class);
}
```
レポートには診断の提供元パッケージが表示されます。
```text theme={null}
[fail] Storage is writable (laravel/doctor): The application cannot write to every required storage directory.
[warn] Horizon is running (laravel/horizon): Horizon is not currently running.
```
## プログラムからの実行
Artisanコマンドを使わずに `Doctor::run()` を呼び出すこともできます。
```php theme={null}
use Laravel\Doctor\Facades\Doctor;
$report = Doctor::only('security')
->except(SomeDiagnostic::class)
->run();
if ($report->hasFailures()) {
// ...
}
```
プログラム実行で修正も適用したい場合は `fixUsing` を設定します。コールバックは修正を提供する失敗診断を受け取り、`false` でスキップ、`true` で通常の修正を適用、または修正オプションの値を返してその選択で修正を適用します。修正が適用されると、Doctorはレポートに反映させるため診断を再実行します。
```php theme={null}
$report = Doctor::fixUsing(
fn ($outcome) => $outcome->fixRequiresOption() ? false : true,
)->run();
$report->fixes();
```
## 出力形式とAIエージェント対応
Doctorはデフォルトで読みやすいCLI出力を行いますが、JSONやGitHub Actionsアノテーション形式も選択できます。
```bash theme={null}
php artisan doctor --format=json
php artisan doctor --format=github
```
[Laravel Agent Detector](https://github.com/laravel/agent-detector) を使ってClaude CodeやCursorのようなAIコーディングエージェント内での実行を検出すると、[Laravel PAO](https://github.com/laravel/pao) と同じ規約に従ったエージェント最適化フォーマットがデフォルトになります。
```json theme={null}
{"tool":"doctor","result":"failed","diagnostics":27,"failed":1,"warnings":1,"notices":0,"passed":19,"skipped":6,"issues":[{"name":".env file exists","status":"fail","summary":"The application does not have an environment file.","fix":"Run `cp .env.example .env`, then review the copied values.","fixable":true}]}
```
`fixable: true` の問題は `--fix` の再実行で修正できます。エージェント外でこのフォーマットを試す場合は `AI_AGENT=test php artisan doctor` を実行します。
## まとめ
`laravel/doctor` は、`php artisan doctor` の実行だけでアプリケーションの設定・環境・インフラの問題を素早く洗い出せるツールです。AIコーディングエージェントとの親和性も高く、Laravel PAOと同じ規約でエージェントが解釈しやすい出力を返すため、CI/CDやAIエージェントによる自動修復ワークフローへの組み込みも検討する価値があります。
ソースコードと最新情報はこちら。
# Laravel新コード解析エコシステム — surveyor / ranger / roster
Source: https://kawax.biz/jp/blog/laravel-ecosystem-analysis
Laravelが公開した静的解析エコシステムを構成する3つのパッケージ(surveyor・ranger・roster)を紹介します。PHPコード解析からパッケージ検出まで、パッケージ開発者・ツール作者が知っておくべき新ツール群を解説します。
この記事はGitHubリポジトリのREADMEとソースコードに基づく情報です。3パッケージはいずれも正式リリース前のBeta版です(2026年4月時点)。
surveyor・ranger・rosterはいずれも**Betaリリース中**です。v1.0.0リリース前にAPIが変更される可能性があります。本番環境での利用は慎重に判断してください。
## 最新リリース状況(2026年4月)
| パッケージ | 最新リリース | 補足 |
| - | - | - |
| `laravel/roster` | `v0.5.1` | `laravel/boost` の `composer.json` で `^0.5.0` が要求され、`BoostServiceProvider` で `Roster::scan(base_path())` が実行される |
| `laravel/ranger` | `v0.1.12` | `composer.json` で `laravel/surveyor:^0.1.0` に依存 |
| `laravel/surveyor` | `v0.1.9` | `ranger` の解析基盤として利用される低レイヤー |
## 概要
Laravelは2026年に入り、コード解析に関連する3つのパッケージを公開しました。これらは単独でも使えますが、相互に連携した**コード解析エコシステム**を形成しています。
```mermaid theme={null}
graph TD
A["laravel/roster
パッケージ検出"] --> B["laravel/ranger
高レベルイントロスペクション"]
B --> C["laravel/surveyor
低レベル静的解析エンジン"]
D["Boost
AI開発支援ツール"] --> A
E["ツール・パッケージ開発者"] --> A
E --> B
E --> C
```
| パッケージ | 役割 | インストール |
| - | - | - |
| `laravel/surveyor` | PHPコードの静的解析エンジン | `composer require laravel/surveyor` |
| `laravel/ranger` | Laravelアプリ全体のイントロスペクション | `composer require laravel/ranger` |
| `laravel/roster` | エコシステムパッケージの検出 | `composer require laravel/roster --dev` |
各パッケージの詳細を順に見ていきましょう。
***
## laravel/surveyor — 静的解析エンジン
[laravel/surveyor](https://github.com/laravel/surveyor) は、PHPファイルをパースしてクラス・メソッド・プロパティ・戻り値の型などの詳細なメタ情報を構造化形式で提供する静的解析ツールです。他のツールやパッケージが利用できる形で情報を抽出することに特化しています。
### インストール
```bash theme={null}
composer require laravel/surveyor
```
### 基本的な使い方
#### ファイルを解析する
```php theme={null}
use Laravel\Surveyor\Analyzer\Analyzer;
$analyzer = app(Analyzer::class);
// ファイルパスで解析
$result = $analyzer->analyze('/path/to/your/File.php');
// 解析済みスコープへアクセス
$scope = $result->analyzed();
// クラス結果へアクセス
$classResult = $result->result();
```
#### クラスを直接解析する
```php theme={null}
$result = $analyzer->analyzeClass(\App\Models\User::class);
$classResult = $result->result();
```
### ClassResultで取得できる情報
```php theme={null}
$classResult = $analyzer->analyzeClass(App\Models\User::class)->result();
// クラス情報
$name = $classResult->name(); // 'App\Models\User'
$namespace = $classResult->namespace(); // 'App\Models'
$filePath = $classResult->filePath();
// 継承関係
$extends = $classResult->extends();
$implements = $classResult->implements();
// メソッド情報
$method = $classResult->getMethod('store');
$returnType = $method->returnType();
$parameters = $method->parameters();
$rules = $method->validationRules(); // バリデーションルールも取得可能
// プロパティ情報
$property = $classResult->getProperty('email');
$type = $property->type;
$visibility = $property->visibility; // 'public', 'protected', 'private'
// 公開メソッド・プロパティの一覧
$publicMethods = $classResult->publicMethods();
$publicProperties = $classResult->publicProperties();
```
### 型システム
Surveyorは充実した型システムを持っており、PHPの型を構造化して扱えます。
```php theme={null}
use Laravel\Surveyor\Types\Type;
// 各種型の生成
$stringType = Type::string();
$intType = Type::int();
$boolType = Type::bool();
$nullType = Type::null();
// ユニオン型(string|null など)
$unionType = Type::union(Type::string(), Type::null());
// 型の判定
use Laravel\Surveyor\Types\StringType;
if (Type::is($returnType, StringType::class)) {
// 文字列型の処理
}
```
### キャッシュ設定
解析結果をキャッシュして繰り返し実行のパフォーマンスを改善できます。
```php theme={null}
use Laravel\Surveyor\Analyzer\AnalyzedCache;
// ディスクキャッシュを有効にする
AnalyzedCache::enableDiskCache(storage_path('surveyor-cache'));
// キャッシュをクリアする
AnalyzedCache::clear();
```
環境変数でも設定できます。
```env theme={null}
SURVEYOR_CACHE_ENABLED=true
SURVEYOR_CACHE_DIR=/path/to/cache
```
### Eloquentモデルの解析
Surveyorはデータベースへの接続を試みてEloquentモデルを特別に解析します。モデルのリレーション・属性・アクセサ・キャストも検出されます。
```php theme={null}
$result = $analyzer->analyzeClass(App\Models\User::class)->result();
// データベース属性が自動検出される
$emailProperty = $result->getProperty('email');
// リレーションメソッドを判定
$method = $result->getMethod('posts');
if ($method->isModelRelation()) {
// このメソッドはリレーション
}
```
SurveyorはEloquentモデルの解析時にデータベースへの接続を試みるため、完全な静的解析ではありません。また、パフォーマンスとメモリ使用量は現在改善中で、コントリビューションを歓迎しています。
***
## laravel/ranger — 高レベルイントロスペクション
[laravel/ranger](https://github.com/laravel/ranger) はsurveyorをラップし、Laravelアプリケーション全体をウォークスルーしてルート・モデル・Enum・ブロードキャストイベント・環境変数・Inertiaコンポーネントなどの情報を収集する高レベルライブラリです。
### インストール
```bash theme={null}
composer require laravel/ranger
```
### 基本的な使い方
コールバック形式で、各コンポーネントが発見されたときの処理を記述します。
```php theme={null}
use Laravel\Ranger\Ranger;
use Laravel\Ranger\Components;
use Illuminate\Support\Collection;
$ranger = app(Ranger::class);
// ルートが発見されるたびに呼ばれる
$ranger->onRoute(function (Components\Route $route) {
echo $route->uri();
});
// モデルが発見されるたびに呼ばれる
$ranger->onModel(function (Components\Model $model) {
foreach ($model->getAttributes() as $name => $type) {
// 属性名と型の処理
}
});
// Enumが発見されるたびに呼ばれる
$ranger->onEnum(function (Components\Enum $enum) {
//
});
// ブロードキャストイベントが発見されるたびに呼ばれる
$ranger->onBroadcastEvent(function (Components\BroadcastEvent $event) {
//
});
// すべてのルートが収集された後に一度だけ呼ばれる
$ranger->onRoutes(function (Collection $routes) {
//
});
// すべてのモデルが収集された後に一度だけ呼ばれる
$ranger->onModels(function (Collection $models) {
//
});
// アプリケーション全体をウォークスルーしてコールバックを発火する
$ranger->walk();
```
### Rangerが収集するコンポーネント
| コレクター | 説明 |
| - | - |
| **Routes** | 全登録ルート(URI・パラメーター・HTTPメソッド・コントローラー・バリデーションルール・レスポンス) |
| **Models** | Eloquentモデルと属性・型・リレーション |
| **Enums** | PHPのBacked Enum(整数・文字列を持つEnum)とケース・値 |
| **BroadcastEvents** | `ShouldBroadcast`を実装したイベントとペイロード |
| **BroadcastChannels** | 登録済みブロードキャストチャンネル |
| **EnvironmentVariables** | `.env`ファイルで定義された環境変数 |
| **Inertia Shared Data** | グローバルに共有されたInertia.js props |
| **Inertia Components** | Inertia.jsのページコンポーネントと期待されるprops |
***
## laravel/roster — パッケージ検出ツール
[laravel/roster](https://github.com/laravel/roster) はプロジェクトにどのLaravelエコシステムパッケージがインストールされているかを検出するツールです。パッケージ開発者やツール作者が「このプロジェクトはInertiaを使っているか?」「Livewireのバージョンは?」といった情報を簡単に取得できます。
### インストール
```bash theme={null}
composer require laravel/roster --dev
```
### 基本的な使い方
```php theme={null}
use Laravel\Roster\Roster;
use Laravel\Roster\Packages;
// ディレクトリをスキャンしてRosterを取得
$roster = Roster::scan($directory);
// インストール済みパッケージの一覧
$roster->packages();
// 本番環境用パッケージのみ
$roster->packages()->production();
// 開発専用パッケージのみ
$roster->packages()->dev();
// 特定パッケージの有無を確認
$roster->uses(Packages::INERTIA); // bool
$roster->uses(Packages::LIVEWIRE); // bool
// バージョン条件を指定して確認
$roster->usesVersion(Packages::INERTIA, '2.0.0', '>='); // Inertia 2.0.0以上か?
$roster->usesVersion(Packages::LIVEWIRE, '3.0.0', '>='); // Livewire 3.0.0以上か?
// JavaScriptパッケージマネージャーの検出
$packageManager = $roster->nodePackageManager(); // 'npm', 'yarn', 'bun' など
```
***
## 実際のユースケース
### AIガイドライン生成ツール(Boost)
[Laravel Boost](https://github.com/laravel/boost) はrosterを使って、インストール済みのパッケージ構成を把握し、AIエージェント(GitHub CopilotやClaudeなど)向けのガイドラインとスキルの生成を自動調整しています。「このプロジェクトはInertiaを使っているか?」「Livewireは入っているか?」という情報を元に、適切なガイドラインファイルを選択してAIエージェントに提供します。
```mermaid theme={null}
sequenceDiagram
participant Boost as Laravel Boost
participant Roster as laravel/roster
participant AI as AIエージェント
Boost->>Roster: Roster::scan(base_path())
Roster->>Boost: packages() [Inertia, Livewire, Pint...]
Boost->>Boost: パッケージごとのガイドラインを選択
Boost->>AI: Inertiaガイドライン、Livewireガイドライン...
```
### パッケージ互換性チェッカーを作る
ユーザーのプロジェクトにインストールされているパッケージに応じて動作を変えるパッケージを開発する場合、rosterが非常に有効です。
```php theme={null}
use Laravel\Roster\Roster;
use Laravel\Roster\Packages;
$roster = Roster::scan(base_path());
if ($roster->uses(Packages::INERTIA)) {
// Inertia向けの処理
if ($roster->usesVersion(Packages::INERTIA, '2.0.0', '>=')) {
// Inertia v2以上向けの処理
}
}
if ($roster->uses(Packages::LIVEWIRE)) {
// Livewire向けの処理
}
// JavaScriptパッケージマネージャーに応じてインストールコマンドを変える
$pm = $roster->nodePackageManager();
echo "Run: {$pm} install your-package";
```
### アプリケーションドキュメント自動生成
rangerを使うと、Laravelアプリのルート・モデル・Enumを自動的に収集してドキュメントを生成するツールを構築できます。
```php theme={null}
use Laravel\Ranger\Ranger;
use Laravel\Ranger\Components;
$ranger = app(Ranger::class);
$docs = [];
$ranger->onRoute(function (Components\Route $route) use (&$docs) {
$docs['routes'][] = [
'uri' => $route->uri(),
// ルートのバリデーションルール・レスポンス型なども取得可能
];
});
$ranger->onModel(function (Components\Model $model) use (&$docs) {
$docs['models'][] = [
'attributes' => $model->getAttributes(),
];
});
$ranger->walk();
// $docs にアプリ全体の構造情報が収集される
```
***
## まとめ
surveyor・ranger・rosterは、Laravelエコシステムにおける**プログラムによるコード解析**の新しい基盤を提供します。
```mermaid theme={null}
graph LR
A["surveyor
PHPファイルをパース
クラス・メソッド・型を抽出"] --> B["ranger
Laravelアプリ全体を走査
ルート・モデル・Enumを収集"]
B --> C["roster
インストール済みパッケージを検出
バージョン・種類を確認"]
```
これらのパッケージは主にパッケージ開発者・ツール作者を対象としており、エンドユーザーが直接使うものではありません。しかし、Laravel BoostのようにLaravel公式ツールの内部でも積極的に活用されており、今後のエコシステム拡大が期待されます。
PHPコードの静的解析エンジン
高レベルイントロスペクションライブラリ
パッケージ検出ツール
# Laravel LSP — Language Server Protocol による IDE 機能拡張
Source: https://kawax.biz/jp/blog/laravel-lsp-introduction
Laravel 公式の Language Server Protocol 実装。エディタに Framework 認識の補完やホバー機能を提供。
この記事はv0.0.27、2026年7月時点の情報です。Packagistに登録され、`composer global require laravel/lsp` でインストールできるようになりました。
## Laravel LSP とは
**Laravel LSP**(Language Server Protocol)は、Laravel フレームワークを認識した IDE 機能をエディタに提供する公式ツールです。[Language Server Protocol](https://microsoft.github.io/language-server-protocol/) は LSP クライアント(エディタなど)と LSP サーバー(Laravel LSP)の間で通信する標準プロトコルで、これにより複数のエディタで統一された開発体験が実現します。
Laravel LSP が提供する機能:
* **補完** — ルート、ビュー、設定キー、翻訳キー、Livewire コンポーネント等の自動補完
* **ホバー情報** — カーソルを重ねると説明やドキュメント、コンテキスト情報を表示
* **診断** — コード上の問題をリアルタイム検出
* **ドキュメントリンク** — ファイルやリソース間のリンク機能
* **クイックフィックス** — 一般的な問題の自動修正提案
* **定義へのジャンプ** — シンボルの定義位置への移動
## なぜ必要か
エディタ標準の PHP 補完では、Laravel Framework の抽象化レイヤーを理解できません。例えば:
* `Route::get()` の第一引数に URI パターンを入力しても補完がない
* `view('users.index')` のビュー名を入力しても、実際のビューファイル名が補完されない
* 設定ファイルのキー(`config('app.name')`)や翻訳キー(`trans('messages.welcome')`)は補完の対象外
* Blade テンプレート内での補完や検証もエディタ標準では対応していない
Laravel LSP はこれらの「Framework 固有のコンテキスト」を理解し、正確な補完や診断を提供します。
## インストール
### グローバルインストール
Composer を使ってグローバルにインストール:
```bash theme={null}
composer global require laravel/lsp
```
Composer の global bin ディレクトリが `PATH` に含まれていることを確認し、以下のコマンドで起動できます:
```bash theme={null}
laravel-lsp
```
### ソースからのインストール
開発版を使う場合は、リポジトリをクローンして実行できます:
```bash theme={null}
gh repo clone laravel/lsp
cd lsp
composer install
php server
```
シェルエイリアスを設定して `laravel-lsp` コマンドを使用できるようにします:
```bash theme={null}
# Zsh の場合
echo 'alias laravel-lsp="php /path/to/lsp/server"' >> ~/.zshrc
source ~/.zshrc
# Bash の場合
echo 'alias laravel-lsp="php /path/to/lsp/server"' >> ~/.bashrc
source ~/.bashrc
```
## エディタ別設定ガイド
Laravel LSP はスタンダードな LSP プロトコルを使用しているため、LSP をサポートするあらゆるエディタで動作します。主なエディタの設定方法を紹介します。
### Sublime Text
公式の [Laravel Sublime Text extension](https://github.com/laravel/sublime-extension) をインストールして設定します。
### Zed
公式の [Laravel Zed extension](https://github.com/laravel/zed-extension) をインストールして設定します。
### VS Code
公式の [Laravel VS Code extension](https://github.com/laravel/vs-code-extension) をインストールして設定します。
### Cursor
Cursor は VS Code 拡張機能に対応しているため、上記の [Laravel VS Code extension](https://github.com/laravel/vs-code-extension) がそのまま使えます。
### Neovim
Neovim 0.11 以上では、カスタム LSP 設定を直接追加できます:
```lua theme={null}
vim.lsp.config("laravel_lsp", {
cmd = { "laravel-lsp" },
filetypes = { "php", "blade" },
root_markers = { "artisan", "composer.json", ".git" },
})
vim.lsp.enable("laravel_lsp")
```
`nvim-lspconfig` を使う場合は、以下のように登録:
```lua theme={null}
local lspconfig = require("lspconfig")
local configs = require("lspconfig.configs")
if not configs.laravel_lsp then
configs.laravel_lsp = {
default_config = {
cmd = { "laravel-lsp" },
filetypes = { "php", "blade" },
root_dir = lspconfig.util.root_pattern("artisan", "composer.json", ".git"),
},
}
end
lspconfig.laravel_lsp.setup({})
```
### OpenCode
`opencode.json` で LSP サポートを有効化し、Laravel LSP をカスタムサーバーとして設定:
```json theme={null}
{
"$schema": "https://opencode.ai/config.json",
"lsp": {
"laravel-lsp": {
"command": ["laravel-lsp"],
"extensions": [".php", ".blade.php"]
}
}
}
```
## GitHub Copilot CLI での設定
GitHub Copilot CLI を使用している場合は、`~/.copilot/lsp-config.json` でグローバル設定できます。別途のエディタ設定は不要です:
```json theme={null}
{
"lspServers": {
"laravel-lsp": {
"command": "laravel-lsp",
"fileExtensions": {
".php": "php",
".blade.php": "blade"
}
}
}
}
```
Copilot CLI の LSP サーバー設定は `initializationOptions` にも対応しているため、後述の詳細設定をすべて使用できます。
## 設定オプション
LSP クライアントは `initializationOptions` 経由で詳細設定を Laravel LSP に渡せます。
### PHP 環境検出
`phpEnvironment` オプションで、プロジェクトデータのインデックス作成に使用する PHP コマンドを制御します。既定は `auto` で自動検出:
| 値 | PHP コマンドの動作 |
| - | - |
| `auto` | Herd → Valet → Sail → Lando → DDEV → ローカル PHP の順で検出 |
| `herd` | `herd which-php` を使用 |
| `valet` | `valet which-php` を使用 |
| `sail` | Sail 実行中に `./vendor/bin/sail php` を使用 |
| `lando` | `lando php` を使用 |
| `ddev` | `ddev php` を使用 |
| `local` | ローカルの PHP バイナリを直接使用 |
検出に失敗したか不正な値が渡された場合は、`php` にフォールバックします。
### 基本設定例
```json theme={null}
{
"phpEnvironment": "auto",
"phpCommand": ["php"],
"definitionProvider": false
}
```
### Pest ヘルパードキュメントブロック
v0.0.27 で追加されたオプションです。Pest のテストや Composer autoload ファイルが変更された時に、Pest ヘルパー用の docblock を自動生成・更新します:
| オプション | 型 | 既定値 | 説明 |
| - | - | - | - |
| `pestGenerateDocBlocks` | `boolean` | `true` | Pest ヘルパーの docblock を生成し、更新し続けるか |
| `pestHelperFilePath` | `string` | `"storage/framework/testing/_pest.php"` | Pest ヘルパーの出力先パス(プロジェクトルートからの相対パス) |
```json theme={null}
{
"pestGenerateDocBlocks": true,
"pestHelperFilePath": "storage/framework/testing/_pest.php"
}
```
### 機能ごとの設定
各機能は個別に有効/無効を切り替えられます。接尾辞は `Completion`、`Diagnostics`、`Hover`、`Link` など:
```json theme={null}
{
"routeCompletion": true,
"routeDiagnostics": true,
"viewDiagnostics": false,
"translationHover": true,
"configLink": true,
"envCompletion": true,
"bladeComponentLink": true
}
```
## 提供される機能一覧
| 機能領域 | 補完 | ホバー | 診断 | リンク | クイックフィックス |
| - | - | - | - | - | - |
| ルート | ✓ | ✓ | ✓ | ✓ | - |
| ビュー & Blade | ✓ | ✓ | ✓ | ✓ | ✓ |
| 翻訳 | ✓ | ✓ | - | - | - |
| 設定 | ✓ | ✓ | ✓ | ✓ | - |
| 環境変数 | ✓ | ✓ | ✓ | ✓ | ✓ |
| アセット & Mix | ✓ | ✓ | ✓ | ✓ | - |
| Middleware | ✓ | ✓ | ✓ | ✓ | - |
| Inertia | ✓ | - | ✓ | ✓ | - |
| Livewire | ✓ | ✓ | - | ✓ | - |
| Auth & Policies | ✓ | ✓ | ✓ | ✓ | - |
| Container Bindings | ✓ | ✓ | ✓ | ✓ | - |
| Validation | ✓ | - | - | - | - |
| Controller Actions | ✓ | - | ✓ | ✓ | - |
| Eloquent | ✓ | - | - | - | - |
## クイックスタート
1. **インストール** — `composer global require laravel/lsp`
2. **エディタ設定** — 上記のエディタ別ガイドを参照
3. **Laravel プロジェクトを開く** — サーバーがルートから routes、views、translations、config などのプロジェクトデータをインデックス化します
4. **補完を使用** — PHP ファイルや Blade テンプレート内で、Framework 認識の補完が自動で動作します
## まとめ
Laravel LSP は、開発者体験を大きく向上させるツールです。エディタの標準機能では対応できない Framework 固有のコンテキストを理解し、より正確で有益な補完・診断を提供します。
**必要要件:**
* PHP 8.2 以上
* Composer
* LSP 対応エディタ (Sublime Text、Neovim、Cursor、VS Code 等)
**参考資料:**
* [Laravel LSP GitHub リポジトリ](https://github.com/laravel/lsp)
* [Language Server Protocol 公式](https://microsoft.github.io/language-server-protocol/)
* [GitHub Copilot CLI LSP 設定ガイド](https://docs.github.com/en/copilot/how-tos/copilot-cli/set-up-copilot-cli/add-lsp-servers)
# Laravel Pennant 実践ユースケース
Source: https://kawax.biz/jp/blog/laravel-pennant
Laravel Pennantの基本を超えた実践的なパターンを解説します。チーム単位のスコープ、緊急キルスイッチ、ダークローンチ、管理コマンドなど、公式ドキュメントだけでは分からないノウハウを紹介します。
基本的な使い方は[ガイドページ](/jp/pennant)を参照してください。このページでは公式ドキュメントには載っていない実践的なパターンを紹介します。
***
## マルチテナント SaaS でのチームスコープ
個人ユーザーではなくチーム(テナント)単位でフラグを管理したい場合は、デフォルトスコープをチームに変更します。
```php theme={null}
// AppServiceProvider
Feature::resolveScopeUsing(fn () => Auth::user()?->currentTeam);
```
これだけで `Feature::active('billing-v2')` が自動的に現在のチームを対象にします。チームメンバーが誰であっても同じチームに属する限り同じ結果が返るため、UI の一貫性が保たれます。
チームのサインアップ日に応じた段階的ロールアウトの例です。
```php theme={null}
use App\Models\Team;
use Illuminate\Support\Carbon;
use Illuminate\Support\Lottery;
use Laravel\Pennant\Feature;
Feature::define('new-billing', function (Team $team) {
// 2024年以降に登録したチームは即時有効
if ($team->created_at->isAfter(new Carbon('2024-01-01'))) {
return true;
}
// 2022〜2023年登録は10%ずつロールアウト
if ($team->created_at->isAfter(new Carbon('2022-01-01'))) {
return Lottery::odds(1 / 10);
}
// 古いチームは慎重に1%から
return Lottery::odds(1 / 100);
});
```
特定チームのみ有効化したい場合(エンタープライズ顧客への先行提供など):
```php theme={null}
// デプロイ後に特定チームだけ手動で有効化
Feature::for($earlyAccessTeam)->activate('new-billing');
```
***
## 緊急キルスイッチ(`before` メソッドの活用)
本番でバグが発覚したとき、コードロールバックなしで即座に機能を無効化できます。クラスベースのフィーチャーに `before` メソッドを追加すると、ストレージの値より先にチェックが走ります。
```php theme={null}
isAdmin()) {
return true;
}
return null; // null を返すと通常の resolve() へ進む
}
public function resolve(User $user): mixed
{
return $user->isPremium() || Lottery::odds(1 / 5);
}
}
```
環境変数 `FEATURES_NEW_CHECKOUT_DISABLED=true` を設定するだけで、DBを触らずに機能を止められます。デプロイ不要のキルスイッチです。
`before` が `null` を返すと `resolve()` が実行されます。`false` を返すと即座に非アクティブとして扱われます。緊急時以外は `null` を返しておきましょう。
***
## スケジュールされたロールアウト
特定日時に自動的に全ユーザーへ公開したいケース。`before` メソッドで実装できます。
```php theme={null}
public function before(User $user): mixed
{
$rolloutDate = Config::get('features.new_api.rollout_date');
if ($rolloutDate && Carbon::parse($rolloutDate)->isPast()) {
return true; // ロールアウト日を過ぎたら全員に公開
}
return null; // まだの場合は通常の resolve() へ
}
public function resolve(User $user): mixed
{
// ロールアウト前は社内メンバーのみ
return $user->isInternalTeamMember();
}
```
```ini theme={null}
# .env
FEATURES_NEW_API_ROLLOUT_DATE=2025-04-01
```
これで `2025-04-01` を過ぎると自動的に全ユーザーに公開されます。デプロイなし、DBなし、Artisanコマンドなしで自動化できます。
***
## ダークローンチ(Shadow Mode)
新しいロジックをユーザーに見せずに本番データで動かし、旧ロジックと結果を比較するパターンです。問題がなければフラグをオンにするだけでリリース完了です。
```php theme={null}
class RecommendationController
{
public function index(Request $request)
{
$legacyResult = $this->getLegacyRecommendations($request->user());
// shadow モードでは新アルゴリズムを実行して比較するが、表示は旧ロジック
if (Feature::for($request->user())->active('recommendation-v2-shadow')) {
try {
$newResult = $this->getNewRecommendations($request->user());
// 差異をログに記録(ユーザーには見せない)
if ($legacyResult !== $newResult) {
Log::channel('shadow_mode')->info('recommendation diff', [
'user_id' => $request->user()->id,
'legacy' => $legacyResult,
'new' => $newResult,
]);
}
} catch (\Throwable $e) {
Log::error('shadow mode error', ['error' => $e->getMessage()]);
}
}
// レスポンスは常に旧ロジックの結果
return response()->json($legacyResult);
}
}
```
ログを確認して差異がなくなったら、フラグを `recommendation-v2` に切り替えるだけです。
***
## イベントを使った A/B テスト結果の収集
公式ドキュメントには `FeatureRetrieved` イベントの言及はありますが、実際のA/Bテスト集計パターンは示されていません。
`FeatureResolved` イベントはフィーチャーの値が**初めて**解決されたときのみ発火します。これを使ってユーザーのバリアント割り当てを記録します。
```php theme={null}
use Laravel\Pennant\Events\FeatureResolved;
use Illuminate\Support\Facades\Event;
// AppServiceProvider や EventServiceProvider に登録
Event::listen(function (FeatureResolved $event) {
if ($event->feature !== 'purchase-button') {
return;
}
// ユーザーへのバリアント割り当て時点で記録
analytics()->identify($event->scope?->id, [
'ab_purchase_button' => $event->value,
]);
});
```
コンバージョン発生時に別途記録すれば、バリアントごとのコンバージョン率を集計できます。
```php theme={null}
// 購入完了時
Event::dispatch(new PurchaseCompleted($user, $product));
```
```php theme={null}
// PurchaseCompleted リスナー
analytics()->track('purchase_completed', [
'user_id' => $user->id,
'ab_purchase_button' => Feature::for($user)->value('purchase-button'),
]);
```
`FeatureResolved` と `FeatureRetrieved` の違い: `FeatureResolved` は初回評価時のみ発火、`FeatureRetrieved` は毎回のチェックで発火します。割り当て記録には `FeatureResolved`、ページビュー追跡には `FeatureRetrieved` が適しています。
***
## キューイングされたジョブでのスコープ
キューのジョブでは認証済みユーザーが存在しないため、フィーチャーチェックが想定外の挙動をすることがあります。ジョブにスコープを明示的に持たせましょう。
```php theme={null}
class SendWeeklyDigest implements ShouldQueue
{
public function __construct(
private readonly User $user
) {}
public function handle(): void
{
// NG: 認証ユーザーが存在しないため常に false になる
// if (Feature::active('new-digest-layout')) { ... }
// OK: ユーザーを明示的に渡す
if (Feature::for($this->user)->active('new-digest-layout')) {
$this->sendNewLayout($this->user);
} else {
$this->sendLegacyLayout($this->user);
}
}
}
```
ジョブのディスパッチ時にフラグを評価してジョブに渡す方法もあります。
```php theme={null}
// コントローラーで評価してジョブに渡す
$useNewLayout = Feature::for($user)->active('new-digest-layout');
SendWeeklyDigest::dispatch($user, $useNewLayout);
```
***
## Artisan コマンドによる管理 UI
フラグを管理する簡単な Artisan コマンドを作れば、デプロイなしで本番フラグを操作できます。
```php theme={null}
argument('feature');
match ($this->argument('action')) {
'activate' => $this->activate($feature),
'deactivate' => $this->deactivate($feature),
'status' => $this->status($feature),
default => $this->error('不明なアクションです'),
};
}
private function activate(string $feature): void
{
Feature::activateForEveryone($feature);
$this->info("✓ {$feature} を全ユーザーに対して有効化しました");
}
private function deactivate(string $feature): void
{
Feature::deactivateForEveryone($feature);
$this->info("✓ {$feature} を全ユーザーに対して無効化しました");
}
private function status(string $feature): void
{
$count = \DB::table('features')
->where('name', $feature)
->where('value', json_encode(true))
->count();
$this->line("{$feature}: {$count} スコープで有効");
}
}
```
```shell theme={null}
php artisan feature activate new-checkout
php artisan feature deactivate new-checkout
php artisan feature status new-checkout
```
***
## フィーチャー名の安全なリファクタリング(`Name` アトリビュート)
クラスベースのフィーチャーをリネームする際、DBに保存済みのフラグ名が変わると全ユーザーのフラグがリセットされてしまいます。`Name` アトリビュートで保存名を固定しましょう。
```php theme={null}
use Laravel\Pennant\Attributes\Name;
// 旧クラス名: CheckoutV2 → 新クラス名: NewCheckoutExperience
// DBには常に 'checkout-v2' として保存される
#[Name('checkout-v2')]
class NewCheckoutExperience
{
public function resolve(User $user): mixed
{
return $user->isPremium();
}
}
```
これでクラス名を自由にリファクタリングしても、DBのデータはそのまま維持されます。
***
## まとめ
公式ドキュメントの基本を押さえたら、以下のパターンで Pennant の真価が発揮されます。
| パターン | 使いどころ |
| - | - |
| チームスコープ | マルチテナント SaaS |
| `before` キルスイッチ | 本番バグの緊急対応 |
| スケジュールロールアウト | 日時指定のリリース自動化 |
| ダークローンチ | 安全な新アルゴリズムの本番検証 |
| `FeatureResolved` イベント | A/B テスト結果の正確な収集 |
| ジョブの明示的スコープ | キュー環境での正確なフラグ評価 |
| 管理 Artisan コマンド | デプロイなしの本番フラグ操作 |
| `Name` アトリビュート | 安全なクラスリファクタリング |
インストールから基本的な使い方まではガイドページを参照してください。
# ⚡Livewire 4入門 — JavaScriptなしでリアクティブなUIを作る
Source: https://kawax.biz/jp/blog/livewire-introduction
LaravelのファーストパーティパッケージLivewire 4を使って、JavaScriptを書かずにインタラクティブなUIを構築する方法を、インストールから実践的なコード例まで解説します。
## Livewireとは
Laravelで動的なUIを作ろうとすると、以前はVue.jsやReactなどのJavaScriptフレームワークを組み合わせるか、自分でAJAXリクエストを書くしかありませんでした。
**Livewire**はその問題を解決するLaravel用パッケージです。PHPとBladeだけでリアクティブなUIを構築できます。フォームのリアルタイムバリデーション、ライブ検索、カウンターなど、従来であればJavaScriptが必要だった機能を、すべてPHPで実装できます。
Livewire 4はLaravel 10以降、PHP 8.1以降で動作します。現在の最新バージョンはLivewire 4です。
### 仕組みの概要
Livewireコンポーネントはサーバー上のPHPクラスとBladeテンプレートの組み合わせです。ユーザーがボタンをクリックしたりフォームに入力したりすると、Livewireは裏側でAJAXリクエストを送り、PHPを実行し、変更された部分だけをページに反映します。開発者はこの仕組みを意識することなく、PHPのみで記述できます。
***
## インストール
Laravelアプリケーションのルートディレクトリで以下のコマンドを実行します。
```shell theme={null}
composer require livewire/livewire
```
Laravelのパッケージ自動検出が有効なので、追加の設定は不要です。
### レイアウトファイルの作成
フルページコンポーネントとして使う場合はレイアウトファイルが必要です。以下のArtisanコマンドで生成できます。
```shell theme={null}
php artisan livewire:layout
```
`resources/views/layouts/app.blade.php` が生成されます。
```blade theme={null}
{{ $title ?? config('app.name') }}
@vite(['resources/css/app.css', 'resources/js/app.js'])
@livewireStyles
{{ $slot }}
@livewireScripts
```
`@livewireStyles` と `@livewireScripts` が、LiverwireとAlpine.jsのアセットを自動で読み込みます。
***
## 最初のコンポーネント
Livewireコンポーネントを生成するArtisanコマンドが用意されています。シンプルなカウンターを作ってみましょう。
```shell theme={null}
php artisan make:livewire Counter
```
このコマンドで `resources/views/components/⚡counter.blade.php` という単一ファイルコンポーネントが生成されます。
ファイル名の ⚡ はLivewireコンポーネントをひと目で識別するためのものです。エディタでの視認性が上がります。不要であれば設定で無効にできます。
生成されたファイルを次のように編集します。
```blade theme={null}
count++;
}
public function decrement(): void
{
$this->count--;
}
};
?>
カウント: {{ $count }}
```
Bladeテンプレートにこのコンポーネントを埋め込むには、通常のBladeコンポーネント構文を使います。
```blade theme={null}
```
ボタンをクリックするたびにページリロードなしでカウントが更新されます。`wire:click` がJavaScriptの代わりにPHPメソッドを呼び出す仕組みです。
***
## プロパティとアクション
### プロパティ — `wire:model`
`wire:model` ディレクティブで、入力要素とコンポーネントのプロパティを双方向バインドできます。
```blade theme={null}
こんにちは、{{ $name }}さん ({{ $email }})
```
デフォルトでは `wire:model` はアクション(フォーム送信など)が実行されたときにのみサーバーと同期します。入力のたびに同期させたい場合は `.live` 修飾子を追加します。
| 記法 | 挙動 |
| - | - |
| `wire:model` | アクション実行時(フォーム送信など)にのみ同期(デフォルト) |
| `wire:model.live` | 入力のたびにリクエストを送信 |
| `wire:model.blur` | フォーカスを外れたときに同期(リクエストは発生しない) |
| `wire:model.live.blur` | フォーカスを外れたときにリクエストを送信 |
### アクション — `wire:click`、`wire:submit`
`wire:click` はクリックイベント、`wire:submit` はフォームの送信イベントにメソッドを紐付けます。
```blade theme={null}
$this->taskName]);
$this->taskName = '';
}
public function render()
{
return $this->view([
'tasks' => Task::latest()->get(),
]);
}
};
?>
@foreach ($tasks as $task)
- {{ $task->name }}
@endforeach
```
***
## リアルタイムバリデーション
Livewire 4では `#[Validate]` アトリビュートでプロパティにバリデーションルールを直接定義できます。
```blade theme={null}
validate();
Post::create([
'title' => $this->title,
'content' => $this->content,
]);
$this->reset(['title', 'content']);
session()->flash('message', '記事を保存しました。');
}
};
?>
@if (session('message'))
{{ session('message') }}
@endif
```
`#[Validate]` を付けたプロパティは更新のたびに自動バリデーションが走ります。`wire:model.live.blur` と組み合わせることで、フォーカスを外れた瞬間にエラーメッセージが表示されるリアルタイムバリデーション体験を実現できます。
`$this->validate()` はフォーム送信時に全プロパティをまとめて検証します。`#[Validate]` による自動バリデーションと二段階で使うのが推奨パターンです。
***
## ライフサイクルフック
Livewireコンポーネントにはいくつかのライフサイクルフックがあります。
| フック | タイミング |
| - | - |
| `mount()` | コンポーネントが最初に生成されたとき(一度だけ) |
| `boot()` | 毎リクエストの開始時(初回・後続リクエスト両方) |
| `updating($property, $value)` | プロパティが更新される直前 |
| `updated($property)` | プロパティが更新された直後 |
| `rendering()` | ビューのレンダリング前 |
| `rendered()` | ビューのレンダリング後 |
| `dehydrate()` | 毎リクエストの終了時 |
### `mount()` — 初期化
`mount()` はコンポーネントの初期化に使います。コンストラクタの代わりです。
```blade theme={null}
name = Auth::user()->name;
$this->email = Auth::user()->email;
}
};
?>
名前: {{ $name }}
メール: {{ $email }}
```
### `updated()` — プロパティ変更後の処理
プロパティが更新されたあとに処理を挟みたい場合は `updated()` を使います。特定のプロパティに絞る場合はメソッド名に含めます。
```blade theme={null}
username = strtolower($this->username);
}
};
?>
ユーザー名: {{ $username }}
```
入力するたびに自動的に小文字へ変換されます。
***
## Laravelとの統合
### Eloquentモデルの活用
Livewireはプロパティに直接Eloquentモデルを保持できます。
```blade theme={null}
user = $user;
}
#[Validate('required|min:2')]
public string $name = '';
public function save(): void
{
$this->validate();
$this->user->update(['name' => $this->name]);
session()->flash('message', 'プロフィールを更新しました。');
}
public function render()
{
return $this->view();
}
};
?>
@if (session('message'))
{{ session('message') }}
@endif
```
### フォームオブジェクト
複雑なフォームはフォームオブジェクトに切り出すことで、コンポーネントをシンプルに保てます。
```shell theme={null}
php artisan livewire:form PostForm
```
```php theme={null}
namespace App\Livewire\Forms;
use Livewire\Attributes\Validate;
use Livewire\Form;
use App\Models\Post;
class PostForm extends Form
{
#[Validate('required|min:3')]
public string $title = '';
#[Validate('required|min:10')]
public string $content = '';
public function store(): void
{
Post::create($this->only(['title', 'content']));
}
}
```
フォームオブジェクトをコンポーネントから使います。
```blade theme={null}
form->validate();
$this->form->store();
$this->form->reset();
session()->flash('message', '投稿を作成しました。');
}
};
?>
```
***
## まとめ
Livewireが特に向いているユースケースをまとめます。
| ユースケース | Livewireで実現できること |
| - | - |
| フォーム処理 | リアルタイムバリデーション、エラー表示 |
| データ一覧 | ライブ検索、ソート、ページネーション |
| カウンターやトグル | ページリロードなしのUI更新 |
| 管理画面 | Eloquentとの直接連携でCRUD操作 |
| ウィザード型フォーム | ステップ管理をPHPで実装 |
Livewireは「Bladeを使ったことがある」Laravelエンジニアなら今日から使い始められます。JavaScriptフレームワークの学習コストなしで、インタラクティブなUIを実現できるのが最大の強みです。
SPA並みの高度なインタラクションが必要な場面ではInertia.jsが向いていますが、フォームや管理画面、データテーブルのような用途であればLivewireの方がシンプルに実装できることが多いです。まず小さなコンポーネント一つから試してみてください。
Livewireの全機能(ファイルアップロード、ページネーション、テストなど)については公式ドキュメントを参照してください。
# HomebrewでPHPとComposerとNode.jsをインストールする(macOS)
Source: https://kawax.biz/jp/blog/mac-setup
macOSでHomebrewを使いPHP・Composer・Node.jsをインストールし、Laravel開発環境を整えるステップバイステップガイドです。
## はじめに
Laravel チームは初心者向けに [Herd](https://herd.laravel.com/) や `php.new` を用意していますが、シニアエンジニアはパッケージマネージャーで各ツールを個別に管理することを好みます。自分でバージョンを制御でき、複数プロジェクトで異なる PHP バージョンを切り替えるのも簡単です。
このガイドでは **Homebrew** を使って PHP・Composer・Node.js(nvm 経由)をインストールし、`laravel new` が動く状態にするまでを解説します。
対象環境: macOS 13 Ventura 以降。Apple Silicon(M1/M2/M3)・Intel どちらにも対応しています。
***
## Homebrew のインストール
Homebrew は macOS 向けのパッケージマネージャーです。まだインストールしていない場合は、ターミナルで以下を実行します。
```bash theme={null}
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```
インストール後、Apple Silicon の場合はシェル設定ファイル(`~/.zprofile` など)に以下の行が自動追加されます。手動で追加した場合は、設定を再読み込みしてください。
```bash theme={null}
eval "$(/opt/homebrew/bin/brew shellenv)"
```
インストールを確認します。
```bash theme={null}
brew --version
```
***
## PHP のインストール
Homebrew の `php` フォーミュラは常に最新の安定バージョンを指しています。Laravel 13 は PHP 8.3 以上が必要です。
```bash theme={null}
brew install php
```
```bash theme={null}
php --version
```
`PHP 8.3.x` 以上が表示されれば成功です。
複数の PHP バージョンを管理したい場合は、バージョン付きフォーミュラをインストールします。
```bash theme={null}
brew install php@8.3
```
バージョンを切り替えるには `brew link` を使います。
```bash theme={null}
brew unlink php
brew link php@8.3 --force --overwrite
```
現在リンクされているバージョンを確認します。
```bash theme={null}
php --version
```
***
## Composer のインストール
Homebrew から直接インストールできます。
```bash theme={null}
brew install composer
```
```bash theme={null}
composer --version
```
`composer global require` でインストールしたパッケージ(Laravel インストーラーなど)を使えるように、`~/.composer/vendor/bin` を `PATH` に追加します。
`~/.zshrc`(または `~/.bashrc`)に以下を追記します。
```bash theme={null}
export PATH="$HOME/.composer/vendor/bin:$PATH"
```
設定を反映します。
```bash theme={null}
source ~/.zshrc
```
***
## nvm のインストール
Node.js は nvm(Node Version Manager)を使ってユーザー単位でインストールします。`root` 権限なしで管理できるため、グローバルな npm パッケージを使う AI ツールや CLI との相性が良いです。
最新のインストールスクリプトは [nvm の GitHub リポジトリ](https://github.com/nvm-sh/nvm) で確認できます。
```bash theme={null}
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
```
インストールスクリプトは自動的に `~/.zshrc`(または `~/.bashrc`)に以下を追記します。追記されていない場合は手動で追加してください。
```bash theme={null}
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
```
設定を反映します。
```bash theme={null}
source ~/.zshrc
```
```bash theme={null}
nvm --version
```
***
## Node.js のインストール
```bash theme={null}
nvm install --lts
```
新しいターミナルセッションでも自動的に使われるよう、デフォルトバージョンを設定します。
```bash theme={null}
nvm alias default node
```
```bash theme={null}
node --version
npm --version
```
***
## Laravel のインストール確認
```bash theme={null}
composer global require laravel/installer
```
```bash theme={null}
laravel new my-app
```
対話的なセットアップが始まります。スターターキットや認証の有無などを選択できます。
```bash theme={null}
cd my-app
php artisan serve
```
ブラウザで `http://localhost:8000` にアクセスし、Laravel のウェルカムページが表示されれば完了です。
***
## Herd との使い分け
| | Homebrew 手動構築 | Herd |
| - | - | - |
| **対象者** | バージョン管理や設定を細かく制御したい開発者 | 手早く始めたい初心者・個人開発者 |
| **PHP バージョン切り替え** | `brew link` で手動 | GUI で簡単に切り替え |
| **ローカルドメイン** | `/etc/hosts` を手動編集 | 自動で `.test` ドメインを設定 |
| **サービス管理** | `brew services` | GUI から起動・停止 |
| **カスタマイズ性** | 高い | 限定的 |
チーム開発や CI 環境と設定を合わせたい場合や、複数バージョンの PHP を頻繁に切り替える場合は Homebrew による手動構築が適しています。
# Laravel Maestro — スターターキット開発のオーケストレーター
Source: https://kawax.biz/jp/blog/maestro-introduction
Laravel公式の新リポジトリ「Maestro」を調査。複数のスターターキットバリアントを一つのモノレポで管理し、コントリビューションを効率化するオーケストレーターの仕組みを解説します。
この記事はソースコード調査に基づく情報です。公式ドキュメントはまだ存在せず、正式リリース前のリポジトリとなります(2026年4月時点)。
## Maestroとは
[Laravel Maestro](https://github.com/laravel/maestro) は、Laravelの[スターターキット](https://laravel.com/starter-kits)群を一元管理するためのモノレポ型オーケストレーターです。
Laravelのスターターキットには、React・Vue・Svelte(Inertia)とLivewireという複数のスタックがあり、さらにそれぞれに認証方式(Fortify・WorkOS)やオプション(Teams・Blank)を組み合わせた15種類以上のバリアントが存在します。Maestroはこれらすべてのバリアントを単一リポジトリで管理し、変更を各スターターキットリポジトリへ自動的に反映する仕組みを提供します。
```mermaid theme={null}
graph TD
A["laravel/maestro
(モノレポ)"] --> B["orchestrator/
ビルドツール"]
A --> C["kits/
ソースファイル"]
A --> D["browser_tests/
ブラウザテスト"]
B --> E["build コマンドで
バリアントを組み立て"]
E --> F["build/
ビルド済みキット"]
F --> G["composer kit:run
で起動・ウォッチ"]
G --> H["変更を kits/ へ
自動反映"]
```
## どんな問題を解決するか
スターターキットが多数のバリアントに分かれていると、一つの修正を全バリアントに反映する作業が煩雑になります。例えば認証フォームのバリデーション修正を React・Vue・Svelte・Livewire のそれぞれに個別にPRを出すのは非効率です。
Maestroはこの問題を「共有レイヤーとバリアントレイヤーの階層構造」で解決します。変更をどのレイヤーに加えるべきかをオーケストレーターが判断し、最も適切な場所に自動的に適用されます。
## スターターキットのバリアント
Maestroが管理するスターターキットは二つのスタックで構成されます。
### Livewire スタック(6バリアント)
| バリアント | 説明 |
| - | - |
| Blank | 認証なしの最小構成 |
| Fortify | Laravel Fortifyによる認証 |
| Fortify (Multi-file Components) | Bladeビューをコンポーネントファイルに分離した構成 |
| Fortify (Teams) | Fortify認証 + Teamsサポート |
| WorkOS | WorkOSによる認証 |
| WorkOS (Teams) | WorkOS認証 + Teamsサポート |
### Inertia スタック(15バリアント)
React・Vue・Svelteの3フレームワーク × Blank・Fortify・WorkOS × Teams有無の組み合わせで、合計15バリアントが存在します。
## リポジトリの構造
```
laravel/maestro/
├── orchestrator/ # ビルドを管理するLaravelアプリ
│ ├── app/Console/Commands/BuildCommand.php
│ ├── app/Enums/StarterKit.php
│ └── scripts/
├── kits/ # スターターキットのソースファイル
│ ├── Shared/ # 全バリアント共通ファイル
│ ├── Livewire/ # Livewire固有ファイル
│ └── Inertia/ # Inertia固有ファイル(React/Vue/Svelte)
└── browser_tests/ # ブラウザテスト
├── bootstrap/
├── common/
└── teams/
```
`orchestrator` ディレクトリ自体がLaravelアプリケーションになっており、スターターキットのビルドと実行を管理します。
## ファイル階層システム
Maestroの核心は「レイヤーを重ねてスターターキットを組み立てる」仕組みです。Livewire(Fortify)の場合、以下の順でファイルがコピーされ、後のレイヤーが前のレイヤーを上書きします。
```mermaid theme={null}
graph LR
A["Shared/Blank
共通ブランク"] --> B["Livewire/Blank
Livewire最小構成"]
B --> C["Shared/Base
共通ベース"]
C --> D["Livewire/Base
Livewireベース"]
D --> E["Shared/Fortify
共通Fortify"]
E --> F["Livewire/Fortify
Livewire Fortify"]
F --> G["build/
完成したキット"]
```
この階層のおかげで「すべてのキットに共通する修正は `Shared/` に、Livewire固有の修正は `Livewire/` に加える」という明確なルールができています。
## コントリビューションの流れ
スターターキットへのコントリビューションは、個別のスターターキットリポジトリではなく、このMaestroリポジトリで行います。
```bash theme={null}
cd orchestrator
php artisan build
```
インタラクティブなプロンプトで対象キットと認証バリアントを選択します。フラグを使って直接指定することも可能です。
```bash theme={null}
php artisan build --kit=vue
php artisan build --kit=react --workos
php artisan build --kit=livewire --teams
php artisan build --kit=vue --workos --teams
```
```bash theme={null}
composer kit:run
```
Laravelの開発サーバーとファイルウォッチャーが同時に起動します。`build/` ディレクトリで行った変更は自動的に `kits/` の適切な場所へコピーされます。
`build/` ディレクトリ内のファイルを編集します。ウォッチャーが変更を検知し、自動的に `kits/` ディレクトリへ反映します。
`kits/` ディレクトリへの変更をコミットしてPRを作成します。マージされると、Maestroが自動的に変更を各スターターキットリポジトリへプッシュします。
`build/` ディレクトリはgitignoreされています。変更はすべて `build/` 内で行い、ウォッチャーに `kits/` へ同期させてからコミットしてください。
## その他の開発コマンド
### リント
```bash theme={null}
# kitsとbrowser_testsにPintを実行(PHPのみ)
composer kits:pint
# PHPリント + 各Inertiaバリアントのフロントエンドリント
composer kits:lint
# 特定のフレームワークのみを対象にする
composer kits:lint -- --vue
composer kits:lint -- --react --svelte
```
### ブラウザテスト
```bash theme={null}
# 全バリアントのブラウザテストを実行
composer kits:browser-tests
# 特定のフレームワーク・バリアントに絞り込む
composer kits:browser-tests -- --vue
composer kits:browser-tests -- --livewire --fortify
```
ブラウザテストはPest + Playwrightで動作します。`browser_tests/` ディレクトリに `bootstrap/`(共通設定)、`common/`(Fortify向け)、`teams/`(Teams向け)の3層構造でテストが整理されています。
### フラグによる絞り込み
各コマンドは `--livewire`・`--react`・`--svelte`・`--vue` フラグと `--blank`・`--fortify`・`--workos`・`--teams` フラグを組み合わせて対象を絞り込めます。
```bash theme={null}
# VueとSvelteのFortifyバリアントのみチェック
composer kits:check -- --vue --svelte --fortify
# 全フレームワークのWorkOSバリアントのみ
composer kits:check -- --workos
```
## WorkOS環境変数の設定
WorkOSバリアントをビルドして実行する場合は、`orchestrator/.env` にWorkOSのクライアントIDとAPIキーを設定します。ビルド時にこれらの値が `build/` ディレクトリの `.env` ファイルにコピーされます。
```bash theme={null}
# orchestrator/.env
WORKOS_CLIENT_ID=your_client_id
WORKOS_API_KEY=your_api_key
```
## 現在の開発状況
* **GitHubリポジトリ**: [laravel/maestro](https://github.com/laravel/maestro)
* **正式リリース**: なし(バージョンタグ・リリースは未公開)
* **最終コミット**: 2026年4月(アクティブに開発中)
* **必要なPHPバージョン**: ^8.2
* **Laravelバージョン**: ^13.0
Maestroはエンドユーザー向けのパッケージではなく、Laravelチームおよびコントリビューター向けの**開発インフラ**として機能しています。スターターキット本体(`laravel/starter-kit-react` など)はMaestroによってこのモノレポから生成・管理されます。
スターターキットへのコントリビューションに興味がある方は、まずMaestroのREADMEをご確認ください。
スターターキット自体の使い方については公式ドキュメントを参照してください。
# Laravel Multiplex — ローカル開発プロセスをまとめて管理するTUI
Source: https://kawax.biz/jp/blog/multiplex-introduction
laravel/multiplexの初期調査。Laravel 13のphp artisan devが使う、複数プロセスのタブ表示・検索・自動再起動に対応したターミナルUIを解説します。
## はじめに
[`laravel/multiplex`](https://github.com/laravel/multiplex) は、複数のコマンドを同時に実行するためのターミナルUI(TUI)です。Laravel 13の`php artisan dev`から利用され、PHP開発サーバー、キューワーカー、ログ監視、Viteなど、ローカル開発に必要なプロセスを1つのターミナルで管理できます。
タブごとにプロセスの出力を表示でき、出力の検索とスクロールにも対応します。終了時には各プロセスの出力が通常のターミナルのスクロールバックへ書き戻されるため、TUIを終了した後もログを確認できます。
## インストールと直接実行
Laravelアプリケーションでは`php artisan dev`が必要な設定を行うため、通常はMultiplexを直接インストールする必要はありません。単独で使う場合は、Node.js 22.13以降を用意してnpmでインストールします。
```bash theme={null}
npm install -g @laravel/multiplex
```
コマンドは`label,command`形式で渡します。
```bash theme={null}
multiplex 'server,php artisan serve' 'queue,php artisan queue:listen' 'vite,npm run dev'
```
## TUIとインラインモード
標準入力と標準出力がTTYの場合はタブ形式のTUIが起動します。`s`でストリーム表示に切り替え、`/`で出力を検索し、`r`で選択中のプロセスを再起動できます。`q`で終了します。
TTYがないCIやパイプ処理では、インラインモードに自動的に切り替わります。各行にプロセスのラベルが付き、出力が到着した順に表示されます。明示的にインラインモードを使う場合は`-i`を指定します。
```bash theme={null}
multiplex -i 'build,npm run build' 'test,npm test'
```
インラインモードでは最後のプロセスが終了すると実行も終了し、コマンドの失敗を終了コードに反映します。JSON形式で処理結果を扱う場合は`--json`を使います。
```bash theme={null}
multiplex --json 'build,npm run build' 'test,npm test'
```
## 自動再起動と終了処理
クラッシュしたプロセスは1秒待ってから最大5回まで自動的に再起動されます。起動から1秒以内に終了したプロセスは、実行ファイルの不足やポート競合など、最初から起動できていない可能性があるため再試行されません。ビルドやマイグレーションのような一度だけ実行するコマンドでは`--no-restart`を指定します。
```bash theme={null}
multiplex --no-restart 'build,npm run build'
```
Multiplexは終了時やシグナル受信時に子プロセスのプロセスグループを終了させます。開発サーバーだけが残ってポートを占有する状態を防ぐため、複数プロセスをまとめて停止できます。
## 注意点
子プロセスには標準入力が渡されません。そのため、`php artisan tinker`やマイグレーションの確認プロンプトなど、入力を要求するコマンドはMultiplexから実行できません。対話的なコマンドは別のターミナルで実行してください。
MultiplexのプログラムAPIも提供されていますが、コマンドは`sh -c`で実行されます。設定ファイルやリクエストなど、信頼できない値をコマンド文字列に埋め込まないでください。
## 参考資料
* [Laravel公式ドキュメント: Artisan - The Dev Command](https://laravel.com/docs/13.x/artisan#the-dev-command)
* [laravel/multiplex README](https://github.com/laravel/multiplex)
# Laravel Nightwatch 入門
Source: https://kawax.biz/jp/blog/nightwatch-introduction
LaravelのホストSaaSアプリケーション監視プラットフォーム「Nightwatch」の概要、Telescope・Pulseとの違い、インストール方法、そして無料プランで実用的に使うための設定を解説します。
## Laravel Nightwatchとは
[Laravel Nightwatch](https://nightwatch.laravel.com) は、Laravelアプリケーションの本番環境を継続的に監視するための**ホスト型SaaSプラットフォーム**です。HTTPリクエスト、SQLクエリ、例外、キュージョブ、ログ、スケジュールタスクなど、アプリケーション全体のテレメトリーデータをリアルタイムに収集・可視化します。
Nightwatchは**有料サービス**(月額課金)です。無料プランでも利用できますが、収集できるイベント数に上限があります。無料プランで実用的に使うには、後述するサンプリングとフィルタリングの設定が必須です。
***
## Telescope・Pulseとの違い
Nightwatchは、Laravelエコシステムにある既存の監視・デバッグツールと目的が異なります。それぞれの用途を整理します。
```mermaid theme={null}
graph TD
A["Laravel 監視ツール"] --> B["Telescope
開発環境のデバッグ"]
A --> C["Pulse
本番環境のパフォーマンス集計"]
A --> D["Nightwatch
本番環境のホスト型監視"]
B --> B1["自前ホスティング
開発時のみ
無料・OSS"]
C --> C1["自前ホスティング
リアルタイムダッシュボード
無料・OSS"]
D --> D1["SaaSプラットフォーム
エージェント常駐が必要
有料サービス"]
```
| ツール | 用途 | ホスティング | 対象環境 |
| - | - | - | - |
| **Telescope** | 開発時のデバッグ・クエリ調査 | 自前(Laravelアプリ内) | ローカル開発 |
| **Pulse** | パフォーマンス指標の集計・表示 | 自前(Laravelアプリ内) | 本番・ステージング |
| **Nightwatch** | 本番アプリのリアルタイム監視 | Laravelホスト型SaaS | 本番環境 |
Telescopeとほぼ同じ情報を収集しますが、Nightwatchはエージェントプロセスを常駐させてデータをクラウドに送信します。そのため、サーバーが落ちていても履歴データを確認でき、複数サーバー・複数アプリケーションを一元管理できます。
***
## アーキテクチャ
Nightwatchは、LaravelアプリとNightwatchクラウドの間にエージェントプロセスを挟む構成を採っています。
```mermaid theme={null}
sequenceDiagram
participant App as Laravelアプリ
participant Agent as Nightwatchエージェント
(php artisan nightwatch:agent)
participant Cloud as Nightwatchクラウド
participant Dashboard as ダッシュボード
(nightwatch.laravel.com)
App->>Agent: イベントデータを送信
(127.0.0.1:2407)
Agent->>Cloud: バッチ送信
Cloud->>Dashboard: 可視化・アラート
```
エージェントはローカル(`127.0.0.1:2407`)で待機し、Laravelアプリからのイベントを受け取ってクラウドに転送します。このため、エージェントプロセスを常時稼働させる必要があります。
***
## インストールと初期設定
### 1. アカウント・アプリケーションの作成
[nightwatch.laravel.com](https://nightwatch.laravel.com) でアカウントを作成し、組織とアプリケーションを登録します。アプリケーション登録後に**環境トークン**が発行されます。
### 2. パッケージのインストール
```bash theme={null}
composer require laravel/nightwatch
```
Telescopeとは異なり、`--dev` フラグは**不要**です。Nightwatchは本番環境での使用を前提としています。
### 3. トークンの設定
`.env` ファイルにトークンを追加します。
```ini theme={null}
NIGHTWATCH_TOKEN=your-api-key
```
### 4. エージェントの起動
```bash theme={null}
php artisan nightwatch:agent
```
エージェントはバックグラウンドで常時稼働させる必要があります。Laravel Cloud、Laravel Forge、Laravel Vapor には専用のガイドが用意されています。Forgeの場合、公式インテグレーションを使うと自動設定されます。
エージェントの状態確認:
```bash theme={null}
php artisan nightwatch:status
```
### 5. テスト環境での無効化
テスト実行時はNightwatchを無効にすることを推奨します。
```ini theme={null}
# .env
NIGHTWATCH_ENABLED=false
```
`phpunit.xml` でも設定できます。
```xml theme={null}
```
***
## 無料プランで実用的に使うための設定
**無料プランには月間イベント数の上限があります。** デフォルト設定(サンプリングレート100%・全データ収集)のままでは、トラフィックの多いアプリケーションではすぐに上限に達してしまいます。以下の設定を必ず適用してください。
### サンプリングレートを下げる
`NIGHTWATCH_REQUEST_SAMPLE_RATE` はデフォルトが `1.0`(全リクエスト収集)です。無料プランでは `0.1`(10%)程度に抑えることを推奨します。
```ini theme={null}
# .env
NIGHTWATCH_REQUEST_SAMPLE_RATE=0.1
```
例外とコマンドは引き続き全件収集する設定例:
```ini theme={null}
NIGHTWATCH_REQUEST_SAMPLE_RATE=0.1 # リクエストは10%のみ
NIGHTWATCH_EXCEPTION_SAMPLE_RATE=1.0 # 例外は全件(デフォルト)
NIGHTWATCH_COMMAND_SAMPLE_RATE=1.0 # コマンドは全件(デフォルト)
```
### クエリ収集を無効にする
データベースクエリはイベント数の大きな割合を占めます。無料プランではクエリ収集を無効にすることで、重要なイベント(例外・リクエスト・ジョブ)の保存余地を確保できます。
```ini theme={null}
# .env
NIGHTWATCH_IGNORE_QUERIES=true
```
### その他のフィルタリング設定
必要に応じてキャッシュイベントやメール収集も無効化できます。
```ini theme={null}
NIGHTWATCH_IGNORE_CACHE_EVENTS=true
NIGHTWATCH_IGNORE_MAIL=true
NIGHTWATCH_IGNORE_NOTIFICATIONS=true
NIGHTWATCH_IGNORE_OUTGOING_REQUESTS=true
```
### 無料プラン推奨設定まとめ
```ini theme={null}
# .env(無料プラン推奨設定)
NIGHTWATCH_TOKEN=your-api-key
NIGHTWATCH_REQUEST_SAMPLE_RATE=0.1
NIGHTWATCH_IGNORE_QUERIES=true
```
この3行を設定するだけで、無料プランでも実用的なアプリケーション監視が実現できます。
***
## 主要機能
### リクエスト監視
HTTPリクエストごとにレスポンスタイム、ステータスコード、ルート情報などを収集します。異常に遅いエンドポイントを特定し、パフォーマンスのボトルネックを発見できます。
### 例外トラッキング
本番環境で発生した未処理の例外をリアルタイムに捕捉します。スタックトレースとソースコードのスニペットが自動的に記録され、原因調査が容易になります。
```ini theme={null}
# 例外のソースコード収集(デフォルト有効)
NIGHTWATCH_CAPTURE_EXCEPTION_SOURCE_CODE=true
```
### ログ収集
Laravelのログシステム(`Log::error()` など)と統合し、構造化ログをNightwatchに送信します。
```ini theme={null}
# 収集するログの最低レベル(デフォルト: debug)
NIGHTWATCH_LOG_LEVEL=error
```
### ジョブ・スケジュールタスク監視
キュージョブやスケジュールタスクの実行履歴、成功・失敗状態、実行時間を追跡します。バッチ処理の問題を素早く特定できます。
### デプロイメントトラッキング
リリースごとの変更点と問題を紐付けます。「このデプロイ後から例外が増えた」という調査が視覚的に行えます。
### アラートと通知
Slack連携やWebhookを使用して、例外の急増やパフォーマンス劣化を即座に通知できます。
***
## TelescopeとNightwatchの使い分け
```mermaid theme={null}
flowchart TD
Q1{"本番環境のデータが
必要?"} -->|はい| Q2{"自分のサーバーに
データを置きたい?"}
Q1 -->|いいえ| T["Telescope
(ローカル開発)"]
Q2 -->|はい| P["Pulse
(自前ホスティング)"]
Q2 -->|いいえ| N["Nightwatch
(ホスト型SaaS)"]
```
* **ローカル開発** → Telescope
* **本番環境の集計ダッシュボードが欲しい** → Pulse
* **本番環境の詳細なトレースやアラートが欲しい** → Nightwatch
3つは相互排他ではなく、PulseとNightwatchを併用することも可能です。
***
## まとめ
Laravel Nightwatchは、本番Laravelアプリケーションの可視性を大幅に向上させる強力なSaaSツールです。導入の際は以下の点を押さえておきましょう。
* エージェントプロセスを常時稼働させる必要がある
* 無料プランは `NIGHTWATCH_REQUEST_SAMPLE_RATE=0.1` と `NIGHTWATCH_IGNORE_QUERIES=true` の設定が実用上必須
* Telescope(開発)・Pulse(集計)・Nightwatch(監視)は役割が異なり、併用できる
詳細な設定については[公式ドキュメント](https://nightwatch.laravel.com/docs/start-guide)および[環境変数リファレンス](https://nightwatch.laravel.com/docs/environment-variables)を参照してください。
ローカル開発でのデバッグにはTelescopeを使います。
# Laravel Package Skeleton — 公式パッケージ用スターターテンプレート
Source: https://kawax.biz/jp/blog/package-skeleton-introduction
laravel/package-skeletonの初期調査。Laravelパッケージ開発のベストプラクティスを集めた公式スターターテンプレート。Pest・Larastan・Pint・Workbench・GitHub Actions CI を含む全部入りの構成。
この記事はソースコード調査に基づく情報です。2026年7月時点で開発中のリポジトリです。
## Laravel Package Skeletonとは
[Laravel Package Skeleton](https://github.com/laravel/package-skeleton) は、Laravelパッケージを作る際のスターターテンプレートです。
```bash theme={null}
git clone https://github.com/laravel/package-skeleton.git my-package
cd my-package
composer install
```
`composer install` を実行すると対話的な設定スクリプト (`configure.php`) が自動起動し、パッケージ名・ベンダー名・ネームスペース・使用する機能を一問一答で設定します。設定後は即座に開発を始められる状態になります。
```mermaid theme={null}
graph TD
A["GitHub で
Use this template"] --> B["composer install"]
B --> C["configure.php が自動実行"]
C --> D{"対話的な設定"}
D --> E["パッケージ名・ベンダー・ネームスペース"]
D --> F["使用する機能を選択"]
E --> G["設定完了"]
F --> G
G --> H["composer test で動作確認"]
```
## なぜこのスケルトンが必要か
Laravelパッケージを「自己流」で作り始めると、テスト環境のセットアップ・静的解析・コードフォーマット・GitHub Actions の設定など、本来のパッケージロジックとは無関係な作業に多くの時間を費やします。
Laravel Package Skeleton は、Laravelチームが実際のパッケージ開発で使うベストプラクティスを一つのテンプレートにまとめたものです。テンプレートを使えば「環境構築」をスキップしてパッケージのロジック実装からすぐに始められます。
## 含まれるツール
| ツール | 役割 |
| - | - |
| [Pest](https://pestphp.com/) | テストフレームワーク |
| [Larastan](https://github.com/larastan/larastan) | Laravel向け静的解析 |
| [Pint](https://laravel.com/docs/pint) | コードフォーマッター |
| [Orchestra Testbench](https://packages.tools/testbench/) | パッケージテスト環境 |
| Workbench | エンドツーエンド開発用アプリ |
## 設定可能なパッケージ機能
`composer install` 時のプロンプトで、必要な機能だけを選択できます。選択しなかった機能に関するスキャフォールドは削除されます。
| 機能 | 説明 |
| - | - |
| Config file | `config/` に設定ファイルを追加 |
| Routes | ルートファイルを追加 |
| Views | Blade ビューを追加 |
| Translations | 言語ファイルを追加 |
| Migrations | マイグレーションファイルを追加 |
| Assets | 公開用アセットを追加 |
| Commands | Artisan コマンドを追加 |
| Facade | ファサードクラスを追加 |
| Boost Skill | AI エージェント用スキルを追加 |
## 設定可能なツール
機能と同様に、プロジェクトに応じてツールのオン/オフも選択できます。
| ツール | 説明 |
| - | - |
| Dependabot | 依存関係の自動更新 PR |
| Issue Template | GitHub Issue テンプレート |
| Changelog | リリース時の自動 CHANGELOG.md 更新 |
| Funding | GitHub Sponsors スポンサーリンク |
| Security Policy | セキュリティ脆弱性報告ポリシー |
## セットアップの流れ
GitHub の **Use this template** ボタンを押して新しいリポジトリを作成するか、直接クローンします。
```bash theme={null}
git clone https://github.com/laravel/package-skeleton.git my-package
cd my-package
```
`composer install` を実行すると `configure.php` が自動起動します。
```bash theme={null}
composer install
```
スクリプトを手動で実行したい場合は `--no-scripts` オプションを使います。
```bash theme={null}
composer install --no-scripts
php configure.php
```
以下の項目を一問一答で設定します。
* Author Name / Email
* Vendor 名 (例: `kawax`)
* Package 名 (例: `my-package`)
* Package 説明文
* Class 名 (例: `MyPackage`)
* 使用する機能のマルチセレクト
* 使用するツールのマルチセレクト
* GitHub リポジトリの自動作成(gh CLI が認証済みの場合)
```bash theme={null}
composer test
```
PHPStan → Pint → 型カバレッジ → Pest の順で全チェックを実行します。
```bash theme={null}
composer serve
```
`http://localhost:8000` にパッケージ確認用の簡易 Laravel アプリが起動します。
## 非対話モード
CI やスクリプトからセットアップする場合は `--no-interaction` フラグを使います。
```bash theme={null}
php configure.php --no-interaction --config --routes
```
機能フラグを指定すると、指定した機能だけが含まれます。フラグを省略するとすべての機能が含まれます。
## GitHub Actions CI
スケルトンに含まれる `tests.yml` は、複数の PHP バージョン・Laravel バージョン・OS の組み合わせでテストを実行するマトリックスビルドです。
```yaml theme={null}
matrix:
os: [ubuntu-latest, windows-latest]
php: [8.3, 8.4, 8.5]
laravel: [12.*, 13.*]
stability: [prefer-lowest, prefer-stable]
```
各ジョブで実行される内容:
1. **PHPStan** (`composer analyse`) — 静的解析
2. **Pint** (`composer lint:check`) — スタイルチェック
3. **型カバレッジ** (`composer test:types`) — 型カバレッジ 100% 確認(Ubuntu のみ)
4. **Pest** (`composer test:unit`) — ユニットテスト(Ubuntu のみ)
## Changelog 自動化
`update-changelog.yml` が GitHub Release をトリガーに `CHANGELOG.md` を自動更新します。`release.yml` で PR ラベル別に変更内容を分類してリリースノートを生成します。
リリースノートのラベル:
| ラベル | 分類 |
| - | - |
| `breaking` | 破壊的変更 |
| `enhancement` | 機能追加 |
| `bug` | バグ修正 |
| `documentation` | ドキュメント |
| `dependencies` | 依存関係 |
| `maintenance` | メンテナンス |
| `skip-changelog` | 変更履歴に含めない |
## configure.php が行うこと
`configure.php` は設定スクリプトで一度だけ実行する bootstrap です。実行後は削除されます。
```mermaid theme={null}
graph LR
A["configure.php 実行"] --> B["プレースホルダーを置換
:vendor_slug/:package_slug
:author_name など"]
B --> C["未使用の機能ファイルを削除"]
C --> D["README_PACKAGE.md → README.md
AGENTS_PACKAGE.md → AGENTS.md"]
D --> E["CLAUDE.md を AGENTS.md にリンク
.claude を .agents にリンク"]
E --> F["スクリプト自体を削除"]
```
## インストール後の GitHub 設定
README に記載されているインストール後の推奨設定:
* **Dependabot PR は手動レビュー** — 自動マージワークフローは含まれない
* **リリースノートラベルの作成** — `breaking`・`enhancement`・`bug`・`documentation`・`dependencies`・`maintenance`・`skip-changelog`・`duplicate`
* **`main` ブランチ保護の設定** — Changelog 自動化は GitHub Actions が `CHANGELOG.md` にコミットするため、ブランチ保護ルールの調整が必要
追加のリポジトリシークレットは不要です。含まれているワークフローは GitHub の組み込み `GITHUB_TOKEN` を使用します。
## 現在の開発状況
* **GitHubリポジトリ**: [laravel/package-skeleton](https://github.com/laravel/package-skeleton)
* **公開時期**: 2026年7月(活発に開発中)
* **注意**: 開発初期段階のため、API や構成は変更される可能性があります
これからLaravelパッケージを作り始める人は、自己流のスケルトンを1から組み立てるよりもこのテンプレートから始めるのが良いでしょう。Laravel チームが長年のパッケージ開発で得たベストプラクティスが詰まっています。
ソースコードと最新情報はこちら。
Laravelパッケージ開発の基礎については公式ドキュメントを参照してください。
# Laravel PAO — AIエージェント向け出力最適化ツール
Source: https://kawax.biz/jp/blog/pao-introduction
laravel/paoの紹介。PHPUnit・Pest・PHPStan・Artisanの出力をAIエージェント環境でJSON形式に圧縮し、トークン消費を最大99.8%削減するLaravel公式パッケージ。
## はじめに
[laravel/pao](https://github.com/laravel/pao) は、PHP開発ツールの出力をAIエージェント向けに最適化するパッケージです。**PAO(PHP Agent-Optimized output)** は、PHPUnit・Pest・Paratest・PHPStan・Laravel Artisanの冗長な出力を、構造化されたコンパクトなJSONへ自動変換します。
GitHub Copilotを含む多くのAIエージェントがトークン数ベースの料金体系へ移行した結果、ツール出力の削減は直接コスト削減につながるようになりました。PAOはこの課題を解決するために設計されており、Laravel スターターキットのデフォルト依存として組み込まれる予定です。
```mermaid theme={null}
graph TD
A["ツール実行
(PHPUnit/Pest/PHPStan/Artisan)"] --> B{"AIエージェント
環境?"}
B -->|Yes| C["JSON形式に圧縮して出力"]
B -->|No| D["通常の出力
(変更なし)"]
C --> E["AIエージェントが
トークン節約しながら処理"]
D --> F["人間が通常どおり確認"]
```
## なぜ重要か
AIエージェントが開発フローに深く組み込まれるにつれて、ツールの出力トークン数がコストと応答速度に直結するようになっています。
テスト数が1,000件あるプロジェクトでは、PHPUnitの出力は数千行になりますが、AIエージェントが必要な情報は「成功・失敗・件数・失敗箇所」だけです。PAOはこの情報を1桁のJSONオブジェクトに圧縮します。
* **テスト出力**: 最大99.8%のトークン削減
* **PHPStan出力**: 構造化JSONで必要な情報だけを提供
* **Artisan出力**: ANSIコード・罫線文字・余白を除去して最大75%削減
## インストール
PHP 8.3以上、PHPUnit 12-13 / Pest 4-5 / Paratest / PHPStan / Laravel 12以上が対象です。
```bash theme={null}
composer require laravel/pao --dev
```
インストールするだけで動作します。PAOはComposerのオートローダーを通じてPHPUnit・Pest・Paratest・PHPStanに自動でフックします。Laravelプロジェクトではサービスプロバイダーが自動検出され、Artisanの出力最適化も有効になります。
PAOはAIエージェント環境を検出した場合のみ有効になります。人間がターミナルで直接実行する場合は完全に無効化され、通常の出力が維持されます。
## 動作するAIエージェント
PAOは以下のAIエージェントを自動検出します。
| エージェント | 検出方法 |
| - | - |
| GitHub Copilot | `COPILOT_MODEL` などの環境変数 |
| Claude Code | `CLAUDECODE` または `CLAUDE_CODE` |
| Cursor | `CURSOR_AGENT` |
| Gemini CLI | `GEMINI_CLI` |
| Devin | `/opt/.devin` ファイル |
| Codex | `CODEX_SANDBOX` などの環境変数 |
## Before / After
### テスト出力(PHPUnit / Pest)
1,000件のテストスイートが次のように変換されます。
**Before(PAOなし)**
```
PHPUnit 12.5.14 by Sebastian Bergmann and contributors.
............................................................. 61 / 1002 ( 6%)
............................................................. 122 / 1002 ( 12%)
...
.......................... 1002 / 1002 (100%)
Time: 00:00.321, Memory: 46.50 MB
OK (1002 tests, 1002 assertions)
```
**After(PAOあり)**
```json theme={null}
{
"tool": "phpunit",
"result": "passed",
"tests": 1002,
"passed": 1002,
"duration_ms": 321
}
```
テスト数に関わらず出力は常に一定サイズです。テストが失敗した場合はファイルパス・行番号・失敗メッセージが含まれます。
### カバレッジなどのプラグイン出力
`--coverage` や `--profile` などのPestプラグインの追加出力はANSIコード・装飾を除去したうえで `raw` 配列に含まれます。
```json theme={null}
{
"tool": "pest",
"result": "passed",
"tests": 1002,
"passed": 1002,
"duration_ms": 1520,
"raw": [
"Http/Controllers/Controller 100.0%",
"Models/User 0.0%",
"Total: 33.3 %"
]
}
```
### PHPStan出力
```json theme={null}
{
"tool": "phpstan",
"result": "failed",
"errors": 2,
"error_details": {
"/app/Http/Controllers/Controller.php": [
{
"line": 9,
"message": "Method Controller::index() should return int but returns string.",
"identifier": "return.type"
},
{
"line": 14,
"message": "Call to an undefined method Controller::doesNotExist().",
"identifier": "method.notFound"
}
]
}
}
```
### Laravel Artisan出力
`php artisan about` などのコマンド出力からANSIコード・罫線文字・ドット区切り・余白が除去されます。
**Before(PAOなし) — 2,111文字**
```
Environment ................................................................
Application Name ................................................... Laravel
Laravel Version ..................................................... 13.3.0
PHP Version .......................................................... 8.5.4
Debug Mode ......................................................... ENABLED
```
**After(PAOあり) — 535文字**
```
Environment ..
Application Name .. Laravel
Laravel Version .. 13.3.0
PHP Version .. 8.5.4
Debug Mode .. ENABLED
```
`about`・`db:show`・`migrate:status` などのコマンドで最大75%のトークン削減が見込めます。
## Laravel スターターキットへの統合
PAOはLaravelスターターキットのデフォルト依存として組み込まれる予定です。新規プロジェクトを作成すれば自動的にインストールされ、AIエージェントを使った開発でトークンコストを抑えた状態ですぐに始められます。
## まとめ
`laravel/pao` はインストールするだけで動作し、AIエージェント環境でのみ有効になるため、既存の開発ワークフローに一切影響を与えません。AIエージェントを使った開発コストを下げたいすべてのPHP・Laravelプロジェクトで導入を検討する価値があるパッケージです。
ソースコードと最新の対応ツール・エージェント一覧はこちら。
# Laravel Passkeys 初期調査(passkeys-server + @laravel/passkeys)
Source: https://kawax.biz/jp/blog/passkeys-introduction
laravel/passkeys-server(PHP)と @laravel/passkeys(npm)を初期調査。インストール、Userモデル統合、ルート、設定、イベント、フロントエンドAPI、型付きエラー、SSR対応まで整理します。
この記事は `laravel/passkeys-server` と `laravel/passkeys` の README に基づく初期調査です。両パッケージはまだタグなしの開発段階です(2026年4月時点)。
## これは何のパッケージか
Laravel の公式リポジトリで、パスワードレス認証(WebAuthn / パスキー)を実装するための 2 つのパッケージが公開されています。
* サーバー側(PHP): [`laravel/passkeys-server`](https://github.com/laravel/passkeys-server)
* クライアント側(JavaScript): [`@laravel/passkeys`](https://github.com/laravel/passkeys)
この 2 つを組み合わせると、Laravel アプリでパスキー登録とパスキーログインを一貫して実装できます。
## サーバー側: `laravel/passkeys-server`
### インストールと初期セットアップ
```bash theme={null}
composer require laravel/passkeys
```
```bash theme={null}
php artisan vendor:publish --tag=passkeys-migrations
php artisan migrate
```
```php theme={null}
use Laravel\Passkeys\Contracts\PasskeyUser;
use Laravel\Passkeys\PasskeyAuthenticatable;
class User extends Authenticatable implements PasskeyUser
{
use PasskeyAuthenticatable;
}
```
必要に応じて設定ファイルも公開できます。
```bash theme={null}
php artisan vendor:publish --tag=passkeys-config
```
### 自動登録されるルート
| 区分 | メソッド | ルート | 役割 |
| - | - | - | - |
| Login (guest) | `GET` | `/passkeys/login/options` | 認証オプション取得 |
| Login (guest) | `POST` | `/passkeys/login` | パスキー検証とログイン |
| Confirm (auth) | `GET` | `/passkeys/confirm/options` | 確認用オプション取得 |
| Confirm (auth) | `POST` | `/passkeys/confirm` | パスキー確認 |
| Management (auth) | `GET` | `/user/passkeys/options` | 登録オプション取得 |
| Management (auth) | `POST` | `/user/passkeys` | 新規パスキー保存 |
| Management (auth) | `DELETE` | `/user/passkeys/{passkey}` | パスキー削除 |
### `config/passkeys.php` の主要オプション
* `relying_party_id`
* `allowed_origins`
* `user_handle_secret`
* `timeout`
* `guard`
* `middleware`
* `throttle`
* `redirect`
### イベント
パッケージは以下のイベントを発火します。
* `PasskeyRegistered`
* `PasskeyVerified`
* `PasskeyDeleted`
### カスタマイズポイント
`Passkeys::authorizeLoginUsing()` で、検証成功後のログイン許可を制御できます。停止したい場合は `false` を返すか、`ValidationException` を投げます。
`GenerateRegistrationOptions` / `GenerateVerificationOptions` / `StorePasskey` / `VerifyPasskey` / `DeletePasskey` を継承してサービスコンテナへバインドし、挙動を差し替えできます。
`PasskeyLoginResponse` などのコントラクトを独自実装して、成功時レスポンス(JSON・リダイレクトなど)をアプリ要件に合わせて変更できます。
## クライアント側: `@laravel/passkeys`
`@laravel/passkeys` はブラウザ側 WebAuthn ceremony を扱う JavaScript クライアントです。
### インストール
```bash theme={null}
npm install @laravel/passkeys
```
### 基本 API
```js theme={null}
import { Passkeys } from "@laravel/passkeys";
await Passkeys.register({ name: "My MacBook" });
await Passkeys.verify();
```
### フレームワークヘルパー
* React: `@laravel/passkeys/react` の `usePasskeyVerify`, `usePasskeyRegister`
* Vue: `@laravel/passkeys/vue` の `usePasskeyVerify`, `usePasskeyRegister`
* Svelte: `@laravel/passkeys/svelte` の `usePasskeyVerify`, `usePasskeyRegister`
### パスキーオートフィル
`autofill: true` を指定すると、`autocomplete="... webauthn"` を持つ input にブラウザのパスキーピッカーを表示できます。サポートされない環境やユーザーキャンセル時は通常フローへフォールバックします。
### 型付きエラー
README では次のエラークラスが公開されています。
* `NotSupportedError`
* `UserCancelledError`
* `PasskeyExistsError`
* `PasskeyError`(ベースクラス)
### SSR 対応
WebAuthn はブラウザ API ですが、各フレームワーク用フックは SSR セーフです。サーバー側では `isSupported` が `false` として扱われ、マウント後に実ブラウザ状態へ更新されます。
## まとめ
* `laravel/passkeys-server`(PHP)と `@laravel/passkeys`(JS)を組み合わせると、Laravel で完結したパスキー認証スタックを構築できます。
* どちらもタグなしの開発段階ですが、Laravel 公式エコシステムとして今後の標準認証手段になる可能性が高いです。
* 早期採用する場合は、README のルート・設定・エラーハンドリング・カスタマイズ拡張点を前提に設計すると安全です。
その後パスキーは **Laravel Fortify の機能として正式に追加されました**。Fortify 経由でパスキーを有効化する場合は、`laravel/passkeys-server` を直接インストールするのではなく `Features::passkeys()` を使います。詳細は [Laravel Fortify とスターターキット](/jp/advanced/fortify) を参照してください。
サーバー側パッケージの最新 README と実装を確認します。
クライアント側パッケージの最新 README と API を確認します。
Fortify 経由でのパスキー有効化手順と、スターターキットとの関係を解説します。
# Pest PHPで始めるLaravelテスト
Source: https://kawax.biz/jp/blog/pest-introduction
Laravel 11からデフォルトになったPest PHPをシニアエンジニア視点で紹介します。PHPUnitとの違い・移行コスト・`arch()`テストの活用まで、実際のプロジェクト導入を想定して解説します。
## なぜPestがLaravelのデフォルトになったか
Laravel 11より、`laravel new` でプロジェクトを作成する際に **Pest** がデフォルトのテストフレームワークとして選択されるようになりました。PHPUnit は長年 PHP の標準的なテストツールとして使われてきましたが、Pest はその PHPUnit をベースにしながら、より簡潔で読みやすいテスト記法を提供します。
PestはPHPUnit上で動作するため、既存のPHPUnitテストはそのまま実行できます。移行は段階的に進められます。
公式が Pest を採用した背景には、テストを書く際の摩擦を減らすという目標があります。クラスを定義してメソッドを書いてという儀式的な手順をなくし、「テストしたいこと」そのものに集中できる記法を提供することで、テストを書く習慣が自然と身につくようになります。
***
## PHPUnitとの主な違い
### テストの記法
最もわかりやすい違いはテストの書き方です。
```php theme={null}
test('ユーザーがログインできる', function () {
$user = User::factory()->create();
$response = $this->post('/login', [
'email' => $user->email,
'password' => 'password',
]);
$response->assertRedirect('/dashboard');
});
```
```php theme={null}
class AuthTest extends TestCase
{
public function test_user_can_login(): void
{
$user = User::factory()->create();
$response = $this->post('/login', [
'email' => $user->email,
'password' => 'password',
]);
$response->assertRedirect('/dashboard');
}
}
```
Pest の `test()` 関数はクロージャを受け取ります。クラスやメソッドの定義が不要なため、テストの意図が一行目から明確です。`it()` も同様に使えます。英語で書く場合は `it('can login', ...)` という自然な文として読めます。
### `expect()` API
Pest の最大の特徴は `expect()` を使ったチェーン形式のアサーションです。
```php theme={null}
test('投稿一覧APIがJSON形式で返る', function () {
$posts = Post::factory(3)->create();
$response = $this->getJson('/api/posts');
expect($response->status())->toBe(200);
expect($response->json('data'))->toHaveCount(3);
expect($response->json('data.0.title'))->not->toBeEmpty();
});
```
`expect($value)->toBe()`, `->toBeNull()`, `->toContain()`, `->toHaveCount()` など、英語として自然に読める形式でアサーションを書けます。複数のアサーションをメソッドチェーンでまとめることもできます。
```php theme={null}
expect($user)
->name->toBe('田中太郎')
->email->toBe('tanaka@example.com')
->is_admin->toBeFalse();
```
### セットアップとティアダウン
PHPUnit の `setUp()` に相当するのが `beforeEach()`、`tearDown()` に相当するのが `afterEach()` です。
```php theme={null}
beforeEach(function () {
$this->user = User::factory()->create();
$this->actingAs($this->user);
});
test('認証済みユーザーはプロフィールにアクセスできる', function () {
$response = $this->get('/profile');
$response->assertOk();
});
test('認証済みユーザーはプロフィールを更新できる', function () {
$response = $this->patch('/profile', ['name' => '新しい名前']);
$response->assertRedirect('/profile');
});
```
### データセット — テーブルドリブンテスト
同じテストロジックを複数のデータで実行したい場合は `dataset` を使います。
```php theme={null}
test('無効なメールアドレスはバリデーションエラーになる', function (string $email) {
$response = $this->postJson('/api/users', [
'name' => '田中太郎',
'email' => $email,
]);
$response->assertUnprocessable();
})->with([
'メールなし' => [''],
'形式不正' => ['notanemail'],
'二重@' => ['a@@example.com'],
]);
```
各データセットのラベル(`'メールなし'` など)がテスト名に付加されるため、どのパターンで失敗したかが一目でわかります。
***
## `arch()` テスト — アーキテクチャの自動チェック
Pest の `arch()` はコードベースの構造を検証するテストです。「コントローラーがモデルに直接依存していないか」「モデルが Eloquent を継承しているか」といったアーキテクチャルールを自動で検証できます。
```php theme={null}
test('モデルはEloquentを継承している', function () {
arch()->expect('App\Models')
->toExtend(Illuminate\Database\Eloquent\Model::class);
});
test('コントローラーはfinalで定義されている', function () {
arch()->expect('App\Http\Controllers')
->toBeFinal();
});
test('サービスクラスはコントローラーに依存しない', function () {
arch()->expect('App\Services')
->not->toUse('App\Http\Controllers');
});
```
`arch()` テストはソースコードを静的解析して実行されます。実際にHTTPリクエストを送ったりデータベースにアクセスしたりしないため、非常に高速です。
Pest にはよく使われるアーキテクチャルールのプリセットも用意されています。
```php theme={null}
test('Laravelのアーキテクチャルールに従っている', function () {
arch()->preset()->laravel();
});
```
`laravel()` プリセットはモデルの命名・コントローラーの継承・ミドルウェアの構造など、Laravelの一般的な慣習に沿ったルールをまとめて検証します。
***
## Laravelプロジェクトでの実践例
### テストの作成
```shell theme={null}
php artisan make:test UserTest
```
Laravel 11 以降でデフォルト設定のまま実行すると、Pest 形式のテストファイルが生成されます。
```php theme={null}
toBeTrue();
});
```
### Laravelのテストヘルパーをそのまま使う
Pest は Laravel の `TestCase` を継承しているため、`actingAs()`、`assertDatabaseHas()`、HTTP テストヘルパーなど、すべての Laravel テストヘルパーがそのまま使えます。
```php theme={null}
use App\Models\Post;
use App\Models\User;
test('ユーザーは自分の投稿を削除できる', function () {
$user = User::factory()->create();
$post = Post::factory()->for($user)->create();
$response = $this
->actingAs($user)
->delete("/posts/{$post->id}");
$response->assertRedirect('/posts');
$this->assertModelMissing($post);
});
test('他ユーザーの投稿は削除できない', function () {
$user = User::factory()->create();
$otherUser = User::factory()->create();
$post = Post::factory()->for($otherUser)->create();
$this
->actingAs($user)
->delete("/posts/{$post->id}")
->assertForbidden();
$this->assertModelExists($post);
});
```
### ファクトリーとデータベーストランザクション
`RefreshDatabase` や `DatabaseTransactions` トレイトも `uses()` で簡単に適用できます。ファイル先頭に書けばそのファイル全体に適用されます。
```php theme={null}
uses(Tests\TestCase::class, Illuminate\Foundation\Testing\RefreshDatabase::class)->in('Feature');
```
`tests/Pest.php` に一度設定しておくと、すべての Feature テストで `RefreshDatabase` が自動的に有効になります。個別のテストファイルで上書きすることも可能です。
***
## 既存PHPUnitテストとの共存方法
Pest と PHPUnit は同じプロジェクト内で共存できます。既存の PHPUnit テストを書き換える必要はなく、新しいテストから Pest 形式で書き始めればよいだけです。
```shell theme={null}
./vendor/bin/pest # Pestで全テストを実行(PHPUnitテストも含む)
./vendor/bin/pest --filter="ユーザー" # テスト名でフィルタリング
php artisan test # ArtisanコマンドでもPestが動く
```
`php artisan test` は Laravel 11 以降、Pest がインストールされている場合は自動的に Pest を使って実行します。
### 移行の進め方
1. まず `tests/Pest.php` に `uses()` の設定を追加する
2. 新しく追加するテストは Pest 形式で書く
3. 既存の PHPUnit テストは動作を確認しながら少しずつ移行する
急いで全テストを書き換える必要はありません。Pest のシンタックスは PHPUnit と比べて学習コストが低いため、チームへの浸透も比較的スムーズです。
***
## まとめ
| 比較項目 | PHPUnit | Pest |
| - | - | - |
| テスト定義 | クラス + メソッド | `test()` / `it()` 関数 |
| アサーション | `$this->assert*()` | `expect()->to*()` |
| セットアップ | `setUp()` | `beforeEach()` |
| データ駆動 | `@dataProvider` | `->with()` |
| アーキテクチャ検証 | なし | `arch()` |
| 実行速度 | 標準 | 同等(PHPUnit上で動作) |
Pest は PHPUnit の置き換えではなく、PHPUnit をラップした上位レイヤーです。Laravel との統合も深く、スターターキット生成時からデフォルトで選択されるほどになっています。既存プロジェクトへの導入コストは低く、新規のテストから試し始めるだけで恩恵を受けられます。
テストを書く量が増えれば、バグの発見が早くなり、リファクタリングへの心理的ハードルも下がります。Pest はその「テストを書くこと自体の摩擦」を減らすための道具です。
データセット、カバレッジ、並列実行など、Pestの全機能については公式ドキュメントを参照してください。
# React入門 — Inertia × Laravel で使う基礎知識
Source: https://kawax.biz/jp/blog/react-introduction
Laravel + Inertia.js で React を使う入門ガイド。laravel/ui から現行スターターキットまでの歴史的経緯と、useForm・usePage などの Inertia React フックを実践的に解説します。
## Reactとは
React は Meta(旧 Facebook)が開発・維持するユーザーインターフェース構築のための JavaScript ライブラリです。宣言的な UI 記述と **コンポーネントベース**のアーキテクチャが特徴で、小規模なウィジェットからフル SPA まで幅広く活用されています。
Reactの核心は**仮想 DOM** を介した効率的な再レンダリングです。状態(state)が変化すると、React は差分だけを DOM に反映するため、手動で DOM を操作する必要がありません。
このページで解説するのは React 19 と Inertia v3 の組み合わせです。Laravel 13 のスターターキットはこの構成をデフォルトで使用します。
### JSX と TSX
React コンポーネントは **JSX**(JavaScript XML)という構文で書きます。HTML に似た記法を JavaScript の中に直接書けます。
```jsx theme={null}
// JSX の例
function Greeting({ name }) {
return こんにちは、{name}さん
}
```
スターターキットでは **TypeScript**(`.tsx`)が標準採用されています。型定義により IDE の補完が強化され、バグを早期に発見できます。
```tsx theme={null}
// TSX の例(TypeScript)
type Props = {
name: string
}
function Greeting({ name }: Props) {
return こんにちは、{name}さん
}
```
Laravel の React スターターキットは TypeScript + TSX が標準です。本ページの例もすべて TSX で記述します。
***
## Laravel でのポジション
### 歴史
React と Laravel の関係は Vue よりやや浅めですが、現在では同等以上の扱いになっています。
```mermaid theme={null}
timeline
title Laravel と React の歩み
2019 : Laravel 6 — laravel/ui に React スキャフォールドを追加
2021 : Laravel 8 — Breeze に Inertia React スタック追加
2022 : Laravel 9 — Vite へ移行
2025 : Laravel 12 — スターターキットを刷新(React / Vue)
2026 : Laravel 13 — Inertia v3 対応スターターキット
```
**Laravel 6(2019年)** で認証スキャフォールドが `laravel/ui` パッケージとして切り離され、Vue と同時に React 版スキャフォールドも提供されました。ただし当時は Vue が主流で React 版の存在感は薄い状況でした。
**Laravel Breeze(2021年)** に Inertia + React スタックが追加されたことで本格的な採用が始まり、**Laravel 12(2025年)** のスターターキット刷新で React が Vue と完全に同列(むしろ最初に表示される)扱いになりました。
### 現在の主流スタイル:Inertia × React
現在の Laravel における React の使い方の中心は **Inertia × React** です。Inertia は API を設計せずに Laravel のコントローラーから直接 React コンポーネントにデータを渡せる「モダンモノリス」アーキテクチャを実現します。
```mermaid theme={null}
graph LR
Browser["ブラウザ"]
Inertia["Inertia.js
(アダプター層)"]
Laravel["Laravel
(コントローラー)"]
React["React
(ページコンポーネント)"]
Browser <-->|XHR / フルページロード| Inertia
Inertia <-->|Inertia レスポンス| Laravel
Inertia -->|props| React
React -->|レンダリング| Browser
```
***
## セットアップ
### スターターキット経由(推奨)
新規プロジェクトで始める場合はスターターキットを使うのが最も手軽です。
```shell theme={null}
laravel new my-app
```
対話式プロンプトで **React** を選ぶと、以下がすべて自動でセットアップされます。
* `inertiajs/inertia-laravel`(サーバーサイドアダプター)
* `@inertiajs/react`(クライアントアダプター)
* `react` + `react-dom`(React 19 本体)
* `@vitejs/plugin-react`(Vite プラグイン)
* TypeScript + `@types/react`
* Tailwind CSS + shadcn/ui コンポーネントライブラリ
* `HandleInertiaRequests` ミドルウェア
* ログイン・登録などの認証画面(Inertia + React + TypeScript で実装済み)
### 手動インストール
既存プロジェクトに追加する場合は、サーバーサイドとクライアントサイドを別々にインストールします。
```shell theme={null}
# サーバーサイド(PHP)
composer require inertiajs/inertia-laravel
# クライアントサイド(JavaScript)
npm install @inertiajs/react react react-dom
npm install --save-dev @vitejs/plugin-react @types/react @types/react-dom typescript
```
次に、`vite.config.ts` に React プラグインを追加します。
```ts theme={null}
import { defineConfig } from 'vite'
import laravel from 'laravel-vite-plugin'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [
laravel({
input: ['resources/css/app.css', 'resources/js/app.tsx'],
refresh: true,
}),
react(),
],
})
```
`resources/js/app.tsx` で Inertia アプリを起動します。
```tsx theme={null}
import { createInertiaApp } from '@inertiajs/react'
import { createRoot } from 'react-dom/client'
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers'
createInertiaApp({
resolve: (name) =>
resolvePageComponent(
`./pages/${name}.tsx`,
import.meta.glob('./pages/**/*.tsx'),
),
setup({ el, App, props }) {
createRoot(el).render( )
},
})
```
手動インストールの詳細(ルートテンプレートの設定やミドルウェアの登録など)は [Inertia 公式ドキュメント](https://inertiajs.com/installation) を参照してください。
***
## ディレクトリ構造
スターターキットでは React のページコンポーネントを `resources/js/pages/` ディレクトリに配置します。
```
resources/js/
├── app.tsx # Inertia アプリの起点
├── bootstrap.ts
├── components/ # 再利用可能な UI コンポーネント
│ ├── ui/ # shadcn/ui コンポーネント
│ └── ...
├── hooks/ # カスタム React フック
├── layouts/ # レイアウトコンポーネント
│ ├── app-layout.tsx
│ └── auth-layout.tsx
├── lib/ # ユーティリティ関数・設定
├── pages/ # Inertia ページコンポーネント(コントローラー名に対応)
│ ├── auth/
│ │ ├── login.tsx
│ │ └── register.tsx
│ ├── dashboard.tsx
│ └── posts/
│ ├── index.tsx
│ ├── create.tsx
│ └── show.tsx
└── types/ # TypeScript 型定義
```
`Inertia::render('posts/index', [...])` と書くと `resources/js/pages/posts/index.tsx` が対応するコンポーネントになります。
***
## JSX 構文の基礎
React は JSX を使います。JavaScript の中に HTML ライクな構文を書くスタイルで、スターターキットのコードを読むために最低限知っておきたいパターンを紹介します。
#### `{}` — 変数展開
JSX 内では `{}` を使って JavaScript の値や式を埋め込みます。
```tsx theme={null}
const name = '世界'
const count = 3
return (
こんにちは、{name}!
2倍は {count * 2}
)
```
#### 条件分岐 — `&&` と三項演算子
React には `v-if` に相当するディレクティブがありません。シンプルな条件には `&&` 演算子、if/else には三項演算子 `? :` を使います。
```tsx theme={null}
{/* 条件が true のときだけ表示 */}
{isLoggedIn && ようこそ!
}
{/* if / else */}
{isLoggedIn ? ようこそ!
: ログイン}
{/* if / else if / else */}
{isLoggedIn
? ようこそ!
: role === 'admin'
? 管理者としてログイン中
: ログイン
}
```
#### リスト描画 — `.map()`
リストの描画には `Array.map()` を使います。効率的な差分更新のために `key` prop は必ず指定します。
```tsx theme={null}
{posts.map((post) => (
- {post.title}
))}
```
Vue の `v-for :key` や Svelte の `{#each}` に相当します。
#### `className` — CSS クラス名
JSX は JavaScript にコンパイルされるため、`class` は予約語です。CSS クラスには `className` を使います。
```tsx theme={null}
{/* HTML: