九保すこひ@フリーランスエンジニア|累計300万PVのブログ運営中
さてさて、このブログは「私が実際に開発をして得た知識」をできるだけ分かりやすくお届けしようというのがテーマになっています。
それは、簡単に言うと「こうやると○○ができます」という何かを作るためのテクニックやソースコードだったりします。
ただ、Laravel
にはそれだけではなく「開発のときしか使わないけど、強力な助っ人になる」という機能があるのをご存知でしょうか。
つまり、ちょっとしたテストや確認をすることが出来るメソッドが用意されていているんですね。
そこで!
今回はそんな「縁の下力持ち」的なメソッド4つを実例とともに紹介したいと思います。
ぜひLaravel
学習者の参考になると嬉しいです😊✨
開発環境: Laravel 6x
目次
変数の中身を表示してくれるdd()
まずはじめは、Laravel
での開発をしているなら外せないメソッドdd()
です。
dd()
は、変数の中身がどうなっているかを表示してくれるメソッドで、特徴としては以下のようになります。
- 変数の中身を表示してくれる
- 変数は文字列であろうが数値であろうが、インスタンスであろうがなんでもOK
- それ以降のコードは実行されなくなる
では、実際の例を見てみましょう。
文字列
まずは文字列です。
$str = '文字列'; dd($str); // ここは実行されません
これを実行すると以下のようになります。
数値
では、次に数値の場合です。
$number = 100; dd($number);
文字列の場合はクォーテーション"
がついていましたが、数値の場合はありませんし、色も違っているので区別がつきやすいですね。
配列
そして、配列です。
$array = [ 'key_1' => [ 'key_2' => [ 'value_1', 'value_2', 'value_2' ], 'key_3' => 'value_4' ] ]; dd($array);
配列の場合、どんなに階層が深くても以下のように表示してくれます。
インスタンス
dd()
はインスタンスの場合でも配列と同じく全データを表示させることができますが、赤枠の部分のようにきちんと何のデータなのかを表示してくれます。
ちなみに、モデルを使ってDBのデータを取得した場合は少し注意が必要です。
$users = \App\User::get(); dd($users);
なぜなら、dd()
は全てのデータを表示してしまうので次のように開発にとっては余計なデータまで表示してしまうからです。(実際DBデータがどこかわかりにくいです😥)
そのため、これを回避するためには以下のようにtoArray()
を使ってください。
$users = \App\User::get(); dd($users->toArray());
すると結果はこうなります。
時間(Carbon)
Laravel
で採用されている時間管理パッケージCarbon
の場合はこうなります。
$dt = new Carbon(); dd($dt);
タイムゾーンも表示してくれて、もしconfig/app.php
でタイムゾーンをAsia/Tokyo
に変更していたらこの内容も以下のように変更になります。
関数(クロージャ)
例えば、以下のように関数をdd()
に入れてみましょう。
$function = function() { return null; }; dd($function);
この場合は、その関数が定義されている場所についての情報を表示してくれます。
複数のデータを表示する
dd()
は1つだけでなく、一気にいくつものデータを確認することができます。使い方は単純にパラメータとして追加していくだけです。
$str = '文字列'; $number = 1; $array = ['value_1', 'value_2', 'value_3']; dd($str, $number, $array);
検索機能
実はdd()
には検索機能がついているのをご存知でしょうか。
もしデータの内容が多い場合は、ショートカットの「Ctrl + F」を押せば検索ボックスが表示され、データ検索をすることができます。
一気に全データを表示する
例えばdd()
を使って階層が深い配列を表示すると、以下のように2段目以降のデータは閉じられたままになっています。
もちろん右向き三角マークをひとつずつクリックしていけば全データを確認できますが、階層が深いとちょっと面倒ですよね。
そんな場合は、右向き三角マークを「Ctrl」キーを押しながらクリックしてみてください。一気にそれ以降の階層すべてを開くことができます。
SQLの内容を表示
ちなみにヘルパー関数としてのdd()
とは違いますが、モデルからDBデータを取得する場合にもdump()
というメソッドが使えます。
$users = \App\User::where('email', 'taro@example.com') ->where('id', 1) ->where('email', 'taro@example.com') ->dd() ->get();
これが便利なのは、コードの途中に挟むことができるという部分です。
例えば、上の例を実行するとこのようになります。
次に、もしdd()
を1つ上に移動させると、
$users = \App\User::where('email', 'taro@example.com') ->where('id', 1) ->dd() // 上に移動させた ->where('email', 'taro@example.com') ->get();
このように、dd()
が実行されるまでのSQL内容が表示されることになります。
※ ただし、この機能はLaravel 5.8.31
で追加されたので比較的新しいバージョンでないと使えません。
変数の中身を表示してくれるdump()
dump()
は、先ほどのdd()
とほぼ同じ機能ですが、実行場所でストップせずそれ以降の部分のコードも実行されることになります。(機能についてはdd()をご覧ください)
$str = '文字列'; dump($str); echo 'ここは実行されます!';
実行結果はこうなります。
もちろんdump()
はSQLにも用意されています。(Laravel 5.8.31
以降)
$users = \App\User::where('email', 'taro@example.com') ->dump() ->get();
logger()で内容をログファイルに書き込む
logger()
を使えば、配列の内容をログファイルに書き出すことができます。保存場所は、/storage/logs
になります。
そのため、dd()
などを使っても変数の中身を確認できないcron
ジョブを使ったタイマー実行などの開発に使うと便利でしょう。
そして、使い方はとてもシンプルでメッセージを指定するだけでOKです。
logger('データ集計に失敗しました');
実行すると以下のようにログファイルが作成されます(すでにファイルが存在している場合は最後の行に内容が追加されます)
実際の中身はこのようになります。
[2019-10-24 06:02:41] local.DEBUG: データ集計に失敗しました
なお、変数の内容もログに残したい場合は、第2パラメータに配列で指定することができます。
$values = ['value_1', 'value_2', 'value_3']; logger('データ集計に失敗しました', [ 'values' => $values, 'time' => now() ]);
結果はこうなります。
[2019-10-24 06:14:42] local.DEBUG: データ集計に失敗しました {"values":["value_1","value_2","value_3"],"time":"2019-10-24 06:14:42"}
ログレベルを変更する
logger()
はそのままではDEBUG
としてログに書き込まれますが、もし深刻度に応じてレベルを指定したい場合は以下のようにします。
logger()->alert('エラーが発生しました'); logger()->critical('エラーが発生しました'); logger()->emergency('エラーが発生しました'); logger()->error('エラーが発生しました'); logger()->warning('エラーが発生しました'); logger()->notice('エラーが発生しました'); logger()->info('エラーが発生しました'); logger()->debug('エラーが発生しました');
結果はこうなります。
[2019-10-24 06:21:05] local.ALERT: エラーが発生しました [2019-10-24 06:21:05] local.CRITICAL: エラーが発生しました [2019-10-24 06:21:05] local.EMERGENCY: エラーが発生しました [2019-10-24 06:21:05] local.ERROR: エラーが発生しました [2019-10-24 06:21:05] local.WARNING: エラーが発生しました [2019-10-24 06:21:05] local.NOTICE: エラーが発生しました [2019-10-24 06:21:05] local.INFO: エラーが発生しました [2019-10-24 06:21:05] local.DEBUG: エラーが発生しました
DB::listen()で実行されたSQL文を確認する
DB::listen()
を使えば、Laravel
で実行されたSQLの内容を表示させることができます。
もちろん特定のSQLだけを確認したい場合は以下のようにdump()
(もしくはdd()
)を使うと便利です。
$users = \App\User::where('email', 'taro@example.com') ->dump() // SQL内容を表示 ->get();
ただ、DB::listen()
の場合は「全てのSQL」を確認することができるので、app/Providers/AppServiceProvider.php
のboot()
中に記述すると、ページ表示の際に実行される全SQLを一気に確認できて便利です。
<?php namespace App\Providers; use Illuminate\Support\Facades\Blade; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { /** * Register any application services. * * @return void */ public function register() { // } /** * Bootstrap any application services. * * @return void */ public function boot() { \DB::listen(function($q){ // SQL文 dump($q->sql); // パラメータ dump($q->bindings); // 実行にかかった時間 dump($q->time); }); } }
そのため、「どのSQLに時間がかかっているか?」をチェックするのに重宝しますし、logger()
を使ってログに書き込んでもいいかもしれません。
Carbon::setTestNow()で時間を指定する
例えば、スケジュールや予約機能を開発していると、例えば「今が2000年1月1日だとすると・・・」という風に頭の中でタイムスリップをしないといけない場面があると思います。
そんな場合に便利なのがCarbon::setTestNow()
です。
以下のように時刻を指定すると、あたかも今がその時間に実行されたように動いてくれますので、テストにはもってこいです。
Carbon::setTestNow('2000/01/01'); // 以降、時間が2000/01/01になったとして実行される echo now(); // 2000-01-01 00:00:00
※ 少し遅いかもしれませんが、消費税が上がる場合のテストなどにもいいかもしれないですね。(おそらくまた上がるので覚えておいて損はしないと思います😂)
また、もし解除をしたい場合はこのようにします。
Carbon::setTestNow(); // 時間指定を解除
さらに、テストの時間が設定されているかどうかもチェックできます。
if(Carbon::hasTestNow()) { echo 'テスト中'; }
おわりに
ということで今回はLaravel
の開発時に便利なメソッドをご紹介しました。
いつも思いますが、Laravel
はホントにオールラウンドで便利な機能を用意してくれているので開発が楽しくなります。
最近のアップデートではそれほど大きな新機能が追加されることは少なくなってきていますが、裏を返せばそれはすでに十分な機能を備えているということだと思いますので「さすが人気者のLaravel!」って感じです。
ぜひ皆さんも今回紹介したメソッドを使って効率よく開発を進めてくださいね。
ではでは〜!