php artisan tinkerの使い方|Laravel Tinkerの基本コマンドとEloquent操作
php artisan tinkerは、Laravelアプリを丸ごと読み込んだ状態でPHPを1行ずつ実行できる対話環境(REPL)を開くコマンドです。コントローラーやルートを書かなくても、Eloquentモデルの検索・作成・更新・削除やリレーションの確認をその場で試せます。この記事では、起動と終了、Eloquentでのデータ操作、リレーション取得、helpやdocなどの組み込みコマンド、そして日本語が入力できないときの原因と対処までを実例で説明します。
まとめ
- 起動は
php artisan tinker、終了はexit・quit・Ctrl+D。LaravelにはTinker(laravel/tinker)が標準同梱されているため追加インストールは不要です。 - 用途はEloquentの動作確認。モデルの
create/find/where/update/deleteやリレーションを、コードを書かずに1行で検証できます。 - 日本語が入力できないのはPHPの
readline拡張がlibedit実装のとき。GNU readlineに切り替えるか、--executeでの非対話実行で回避します。 - 本番DBには直接つながる。取り消しの効かない更新・削除を対話で打つのは避け、スクリプトとトランザクションで守ります。
以下で、それぞれのコマンドと具体的な書き方を順に見ていきます。
Tinkerとは何か(PsySHベースのREPL)
REPLとしてTinkerができること
Tinkerは、PHP製のREPLであるPsySHの上にLaravelの起動処理を載せたものです。REPLは「入力→評価→結果表示」を繰り返す対話シェルで、Tinkerを起動するとフレームワークがブートストラップされ、Eloquent・キュー・イベント・設定値・サービスコンテナなどアプリ内のあらゆるオブジェクトにコマンドラインから触れます。パッケージ名はlaravel/tinkerで、2026年時点の最新は3.0系(v3.0.2、内部でpsy/psysh 0.12系を利用、PHP 8.1以上・Laravel 13まで対応)。Laravel本体に最初から含まれるため、通常はインストール不要です。
起動と終了の方法
プロジェクトのルートで次を実行するとプロンプトが>>>に変わり、対話モードに入ります。
php artisan tinker
終了するときはexitまたはquitと入力するか、Ctrl+Dを押します。実行結果はそのまま画面に返るため、たとえば1 + 1と打てば2が、now()と打てば現在時刻のCarbonインスタンスが表示されます。式の最後にセミコロンは不要です。
Eloquentでのデータ操作(作成・検索・更新・削除)
Tinkerの主な使い道は、Eloquentモデルの動作をその場で確かめることです。Laravel 8以降のモデルはApp\Models名前空間にあるため、App\Models\Userのように完全修飾名で呼び出します。モデル名とテーブル名の対応はLaravelの規約で自動解決されます(対応の詳細はLaravelの命名規則一覧|テーブル・モデル・コントローラーからコーディング規約までを参照)。
データを作成する(create・factory)
1件を作るならcreateに配列を渡します。テスト用にまとまった件数が欲しいときはfactoryが便利です。
App\Models\User::create([
'name' => 'Taro',
'email' => '[email protected]',
'password' => bcrypt('secret'),
]);
App\Models\User::factory()->count(3)->create();
createを使うにはモデルの$fillableに対象カラムを登録しておく必要があります。factoryはモデルファクトリ(database/factories)が定義されている前提で動きます。
データを検索する(find・where・LIKE)
主キー指定はfind、条件指定はwhereを使います。部分一致はlike演算子と%を組み合わせます。
App\Models\User::find(1);
App\Models\User::where('email', '[email protected]')->first();
App\Models\User::where('name', 'like', '%太郎%')->get();
get()はコレクションを、first()は1件を返します。件数だけ知りたいときはcount()、存在確認はexists()で十分です。
データを更新する(save・where update)
取得したモデルの属性を書き換えてsaveする方法と、条件に一致する行をまとめて更新する方法があります。
$user = App\Models\User::find(1);
$user->name = 'Jiro';
$user->save();
App\Models\User::where('id', 1)->update(['name' => 'Jiro']);
updateによる一括更新はモデルの取得を挟まないぶん速い反面、updated_at以外のモデルイベントが発火しない点に注意します。
データを削除する(delete・ソフトデリート)
単純な削除はdeleteです。モデルがSoftDeletesトレイトを使っている場合は物理削除ではなくdeleted_atに日時が入り、withTrashed()で復元対象を取得してrestore()で戻せます。完全に消すにはforceDelete()を使います。
App\Models\User::find(1)->delete();
App\Models\User::withTrashed()->find(1)->restore();
App\Models\User::find(1)->forceDelete();
外部キー制約がある子レコードを残したまま親を削除するとエラーになるため、削除順序かカスケード設定を確認してから実行します。
リレーション経由で関連データを取得する
Tinkerはリレーションの動作確認にも向きます。定義済みのリレーションはプロパティのように参照でき、hasMany・belongsTo・belongsToManyのいずれも同じ書き味です。
$user = App\Models\User::find(1);
$user->posts; // hasMany: そのユーザーの投稿一覧
$post = App\Models\Post::find(1);
$post->user; // belongsTo: 投稿の作成者
$user->roles; // belongsToMany: 中間テーブル経由のロール
ループ内で$user->postsのように都度アクセスするとN+1クエリになります。件数が多いときはApp\Models\User::with('posts')->get()のようにwithで先読み(Eager Loading)してから確認すると、発行クエリを抑えられます。リクエスト単位で実際に何本のクエリが飛んだかを追うならLaravel Telescopeとは何か?その機能と重要性を徹底解説と併用すると把握しやすくなります。
作業を速くする組み込みコマンド
Tinker(PsySH)には、変数やクラスを調べるためのコマンドが用意されています。使い方に迷ったらまずhelpを打ちます。
| コマンド | 用途 |
|---|---|
| help | 使えるコマンドの一覧を表示 |
| ls | スコープ内の変数・メソッド・定数を一覧 |
| doc | クラスや関数のドキュメントを表示(例 doc collect) |
| show | 対象のソースコードを表示(例 show App\Models\User) |
| dump | 値を整形して出力 |
| whereami | デバッグ中に現在位置を表示 |
| history | 過去に入力したコマンドを再表示 |
直前に発生した例外のスタックトレースはwtf(詳細はwtf -a)で確認できます。またTinkerからは一部のArtisanコマンドも実行でき、実行を許可するコマンドは設定ファイルで制御します。php artisan vendor:publish --provider="Laravel\Tinker\TinkerServiceProvider"でconfig/tinker.phpを生成すると、Tinker内で実行できるArtisanコマンドの許可リスト(既定はclear-compiled・down・env・inspire・migrate・migrate:install・optimize・up)やエイリアス設定を編集できます。
日本語が入力できないときの原因と対処
Tinkerで日本語を打つと文字が消える、確定できないという不具合は、Tinker固有の問題ではなくPHPのreadline拡張の実装差に由来します。readlineはGNU Readlineとlibedit(EditLine)のどちらかで実装されており、libedit実装は多バイト文字の行編集に対応していないため日本語入力が壊れます。macOSのHomebrew版PHPなど、libeditでビルドされた環境で起きやすい問題です。
どちらの実装かを確認する
次のコマンドで自分のPHPがどちらを使っているか判別できます。
php -i | grep -i readline
出力にReadline Support => enabledとあり、ライブラリ名がEditLine wrapperならlibedit(日本語が壊れる側)、GNU readlineなら問題なく入力できます。
readline実装を切り替える手順
- GNU readlineでビルドしたPHPに切り替えるのが根本対処です。ソースからなら
--with-readlineを付けて再ビルドし、パッケージ管理で読み替え可能な環境ならreadline版へ入れ替えます。 - libeditを新しい版へ更新して共有ライブラリのリンクを張り替える方法もあります(Linuxで採られる対処)。
- すぐに直せない場合は
--executeでの非対話実行や、対象の日本語を含む処理をファイルに書いて読み込ませる回避策が確実です(次章)。
DockerやLaravel Sailで文字化けする場合は、readlineの実装に加えてコンテナのロケール(ja_JP.UTF-8やen_US.UTF-8)とmbstringの設定も合わせて確認します。
対話せずに実行する方法と本番環境での注意
Tinkerは対話利用が基本ですが、CI・デプロイ手順・調査用スクリプトに組み込むなら非対話実行が向きます。1行だけなら--executeにコードを渡します。まとまった処理はファイルにして起動時の引数で読み込ませます。
php artisan tinker --execute="echo App\Models\User::count();"
php artisan tinker path/to/script.php
ここで強く言えるのは、本番環境でTinkerを対話モードのまま更新・削除に使うべきではないということです。Tinkerは設定されたDBへそのまま接続するため、本番で打ったdeleteやwhere忘れのupdateは取り消せません。本番でデータを触る必要があるときは、レビュー済みのスクリプトを--executeやファイル読込で流し、DB::transaction()で囲んで途中失敗時にロールバックできるようにします。動作確認はステージングやローカルで済ませ、本番では読み取り以外を極力避けるのが安全です。テスト用データの生成・投入は、Tinkerでの都度実行よりもLaravelのテスト自動化をDuskで実装する方法|インストールからCI実行までで扱う自動テストやシーダーに寄せると再現性が高まります。
よくある質問
php artisan tinkerとは何をするコマンドですか?
Laravelアプリを読み込んだ状態でPHPを対話実行するREPLを起動するコマンドです。PsySHを基盤にしており、Eloquentモデルの操作やリレーションの確認、設定値の参照などをコードファイルを作らずに試せます。
Tinkerは別途インストールが必要ですか?
不要です。laravel/tinkerはLaravelに標準同梱されており、新規プロジェクトなら最初からphp artisan tinkerが使えます。何らかの理由で外している場合のみcomposer require laravel/tinkerで追加します。
Tinkerを終了するにはどうすればいいですか?
exitまたはquitと入力するか、Ctrl+Dを押すと通常のコマンドラインに戻ります。
Tinkerで日本語が打てないのはなぜですか?
PHPのreadline拡張がlibedit(EditLine)実装だと多バイト入力に対応しないためです。php -i | grep -i readlineで実装を確認し、GNU readline版のPHPに切り替えると解決します。応急処置は--executeでの非対話実行です。
Tinkerと通常のphp artisanコマンドの違いは何ですか?
php artisan tinker以外のArtisanコマンドは、あらかじめ定義された1つの処理(マイグレーションやキャッシュ削除など)を実行して終了します。Tinkerは処理を固定せず、任意のPHP・Eloquentを1行ずつ試せる対話環境である点が異なります。