LaravelでWebアプリケーション開発をしていく中で簡単かつ絶対に使えるようになっておくべきデバッグ方法を2つご紹介します。
この記事で2つ紹介するのですが正直、Xdebugというデバッグツール(正確にはPHPの拡張機能)を使うとさらにデバッグ効率&開発効率が上がるのでXdebugを使えるようになるのがベストです。
Xdebugの導入方法&使い方を知りたい方は以下の記事を読んでみてください。

ただ、Xdebugを使うためには色々設定が必要なので、Laravel初心者はまずはこの記事でご紹介するデバッグ方法を身につけるのが良いかと思います。
この記事で紹介する2つの方法が使えたらそこまで開発には困らないかなと思います。(開発効率の面は別として)
というわけで早速説明していきます。
なお、この記事はLaravelの使用経験がある程度ある方にとっては当たり前な内容になっていますm(__)m
Laravelの学習にオススメな教材やサイトはこちらにまとめています。

よく使うデバッグ方法2つ
結論、この2つです。
- dd() / ddd()
- Log::debug()
(正確に言うとdd()とddd()は別物なので3つですが…)
それぞれ触れていきます。
バージョン
念のため、明記しておきます。
$ composer -V
Composer version 1.10.20 2021-01-27 15:41:06
$ php artisan --version
Laravel Framework 6.20.16
サンプルケース
例として「記事投稿アプリで特定のidの記事の編集画面表示の処理」を考えます。
(SPAではなく、LaravelのBladeを使う想定)
View(Bladeファイル)からControllerのアクションに記事(Article)クラスのオブジェクト(=編集する記事データ)を渡して編集画面に遷移する仕様とします。
<?php
class ArticleController extends Controller
{
// 略
/**
* 記事編集画面表示
*
* @param App\Article $article
* @return \Illuminate\Http\Response
*/
public function edit(Article $article)
{
return view('articles.edit', compact('article');
}
// 略
}
引数にオブジェクトを渡すとそのオブジェクトのidをよしなに取得してくれて、ルーティングのパラメータにセットしてくれるの便利ですよね。
(ちゃんとidを渡した方が良いかもしれませんが)
dd() / ddd()
dd() / ddd()とは
dd()もddd()もデバッグ用のヘルパー関数(単にヘルパーとも呼ばれることもある)です。
ヘルパー関数とは「PHPとは別にLaravelや各パッケージが用意している関数」のこと。
デバッグ関数 | 概要 |
---|---|
dd() | Laravel本体のヘルパー関数 |
ddd() | facade/ignitionのヘルパー関数 |
dd()はLaravelにデフォルトで搭載されているヘルパー関数で、ddd()はLaravel6.xから追加されたfacade/ignition
というパッケージのヘルパー関数です。
facade/ignition:Laravel Ignition Introduces the ddd() Helper
ddd()はLaravel自体に搭載されているわけではないので公式ドキュメントには載っていません。
とはいえ、Laravelに始めから含まれているパッケージなのでComposerでパッケージを追加する必要もないです。
ddd()の存在を知らない方も意外と多いんじゃないのかなと思います。
dd()でのデバッグ結果
dd()はLaravelでは1番ポピュラーなデバッグ用ヘルパー関数です。
dd()(ddd()も)の機能は
- ()の中に入れたもの(文字列・変数)の中身をブラウザに表示して
- そこで処理を止める
です。
PHPで表現すると以下のコードをLaravelではdd();の1行で表現できるわけです。
(Laravelでも以下のコードは使えます)
<?php
// デバッグ
dump($val);
// 処理を止める
die;
では、editアクションの引数に渡した記事データ($article)の中身を見るために以下の位置にdd()を仕込みます。
<?php
class ArticleController extends Controller
{
// 略
/**
* 記事編集画面表示
*
* @param App\Article $article
* @return \Illuminate\Http\Response
*/
public function edit(Article $article)
{
// dd()を入れて引数に渡されたArticleクラスのオブジェクトを中身を見る
dd($article);
return view('articles.edit', compact('article');
}
// 略
}
この状態で編集画面へのリンクを設定すると、以下の画面になります。

オブジェクトの場合、
- attributes:デバッグ対象のオブジェクトが持つプロパティ情報
- relations:デバック対象のリレーション関係にあるオブジェクトのプロパティ情報
を見ることが多いです。
ddd()でのデバッグ結果
ddd()はdd()の上位互換と思って貰えたら良いかと思います。
(ただ、dd()はLaravel本来の機能、ddd()はLaravelに組み込まれているパッケージの機能でありそこは根本的には異なる)
上位互換=取得できる情報が多いというニュアンスです。
dd()の時と同様、editアクションの引数に渡した記事データ($article)の中身を見るために以下の位置にdd()を仕込みます。
<?php
class ArticleController extends Controller
{
// 略
/**
* 記事編集画面表示
*
* @param App\Article $article
* @return \Illuminate\Http\Response
*/
public function edit(Article $article)
{
// ddd()入れて引数に渡されたArticleクラスのオブジェクトを中身を見る
ddd($article);
return view('articles.edit', compact('article');
}
// 略
}
以下がデバッグ結果です。と言いたいところなのですが、ddd()でデバッグすると画面にタブがあり、dd()に比べて色々な情報を見ることができるので、各タブの説明を軽くします。
Debugタブ(初期表示)
背景の色が黒ではないですが、dd()で表示される内容と同じです。

Stack Traceタブ

Stack Trace(スタックトレース)の説明は以下です。
エラーが発生するまでに、どんな処理を、どの順番で呼び出したか表現したもの
https://wa3.i-3-i.info/word13281.html
今回のように処理を途中で中断した場合は中断したところまでの処理の流れを追えるようになっています。
この画面はエラーが発生時にブラウザに表示される画面ですね。
今回の場合でいうと以下のことの流れであることがわかります。
public/index.php
の55行目がまずは実行- 最終的に
app/Http/Controllers/ArticleController.php
の89行目(ddd($article);
)が実行されて処理が中断されている
(この間に44個の工程があることもわかる)
Requestタブ

リクエストの情報が記載されています。
(リクエストパラメータとかはわからない)
- HTTPメソッド(上記画面ではGET)
- CSRFトークンの値
- リクエストヘッダーの中身
などが一目でわかります。
Appタブ

- Controller:実行したアクションメソッド
- Route name:ルーティング名
- Route Parameters:アクションメソッドに渡したパラメーター(引数にあたる)
- Middleware:ルーティングに設定したミドルウェア
上記の情報などが一目で確認できます。
Userタブ

Userタブではログイン中のユーザーの情報が表示されます。
dd(Auth::user());
で取得できるUserモデルのオブジェクトの情報が表示されます。
Contextタブ

- Repository:GitHubのリポジトリ
- Message:最新のコミットメッセージと
- Laravel version:Laravelのバージョン
- Laravel locale:言語設定
- Laravel config cache:設定ファイルのキャッシュをクリアしたか(※)
- PHP version:PHPのバージョン
(※)
上記画面ではLaravel config cacheがfalseになっていますが、$ php artisan config:cache
を実行した場合はtrueになります。
config系のキャッシュをクリアしてない(=config系の設定が反映されてない)ことに起因するエラーの発見もしやすくなりそうですね。
Log::debug()
もう一つはLogファサード(Facades)を使ったデバッグ方法です。
公式ドキュメントの日本語訳のページはこちらです。
dd()/ddd()との違いを簡単に表すと以下の通り。
デバッグ方法 | 処理をそこでで止めるか | デバッグ情報の出力先 |
---|---|---|
dd()/ddd() | 止める | ブラウザ |
Log::debug | 止めない | storage/logs/〜.log |
Log::debugという文字通り、ログファイルにデバッグ(確認したいものを出力)する方法です。
dd()、ddd()のケースを同じく、以下のように書きます。
<?php
// Logファサードを使うために追加
use Illuminate\Support\Facades\Log;
class ArticleController extends Controller
{
// 略
/**
* 記事編集画面表示
*
* @param App\Article $article
* @return \Illuminate\Http\Response
*/
public function edit(Article $article)
{
// Log::debug()を入れる
Log::debug(print_r($article, true));
return view('articles.edit', compact('article');
}
// 略
}
ログファイルにデバッグする場合は以下の作業が必要です。
- Logファサードを使うために
use Illuminate\Support\Facades\Log;
を追記 - デバッグしたい位置に
Log::debug();
を入れる
今回はオブジェクトを出力したいので、print_r
関数を使ってログに成形され見やすい情報で出力しています。
[2021-06-17 16:40:25] local.DEBUG: App\Article Object
(
[fillable:protected] => Array
(
[0] => title
[1] => category_id
[2] => summary
[3] => url
)
[connection:protected] => mysql
[table:protected] => articles
[primaryKey:protected] => id
[keyType:protected] => int
[incrementing] => 1
[with:protected] => Array
(
)
[withCount:protected] => Array
(
)
[perPage:protected] => 15
[exists] => 1
[wasRecentlyCreated] =>
[attributes:protected] => Array
(
[id] => 1
[user_id] => 1
// 長いので省略
[created_at] => 2021-05-23 22:10:04
[updated_at] => 2021-05-23 22:10:04
[deleted_at] =>
)
[original:protected] => Array
(
[id] => 1
[user_id] => 1
// 長いので省略
[created_at] => 2021-05-23 22:10:04
[updated_at] => 2021-05-23 22:10:04
[deleted_at] =>
)
// 長いので省略
)
見比べていただけるとわかりますが、dd()でデバッグした時と出力結果は同じです。
なのでオブジェクトのプロパティを見たい時はattributesを見ればOKです。
その他のデバッグ方法
Laravelには他にもデバッグ方法があります。(他にもあるかもしれません)
- Laravel Debugbar(パッケージ)を使う
- tinkerを使う
この記事は割愛しますが、また別の記事で説明できたらと思います。
Xdebugでのデバッグ方法はこちら

最後に
Laravelに限らずWebアプリケーションの開発にはデバッグは必須なので、しっかり身につけておきましょう。
理想はXdebugを使えることですが、まずはdd()(ddd())とLog::debugを使いこなせたらデバッグすることには困らないと思います。
デバッグしまくりましょう。
Laravelのオススメ教材
ドキュメント
- 公式ドキュメント

- 公式ドキュメントの日本語訳(※非公式)
コメント