#LaravelのFacadeを使う時のお作法が分からなすぎる問題を解決(納得)してみた。
Laravelを使い始めて、
コントローラーで処理を書いて、DB使うならモデル作って、ルートの指定はweb.phpに書いて、bladeエンジンにテンプレートを書いて(HTMLを書いて)いいけばいいんでしょ!
ってくらいの駆け出しレベルの時に、ふと悩むポイントがあります。
それは「Facadeってなんや?」ということ。
DB::table('users')->where('id',1)->first();
の***DB::とか、
$name = Request::input('name');
のRequest::***そんなのですね。
偉い人に「ファサードに入ってるから使えばいいじゃん」なんて言われた日には、「あぁ~ファサードですよね。はいはい、どこやったなぁ…ここら辺に置いといたんだけど…(やべぇ…)」なんてことになりますよね。
ってことで今回はFacadeを使うときのお作法をざっくりと分解してみました。
・どうやってFacadeは動いているのか?
・なんで色々なところに色々な記述を食わる必要があるのか?
ということを自分でFacadeを書いて使えるようにするとざっくり理解することができたので、その過程を徒然なるままに書かせていただきます。(あくまで備忘録テイストで…)
#そもそもFacadeとは?
LaravelにおけるFacadeとは、何かの便利機能(クラス)を使いたい時の***便利ツール集(工具箱)***みたいな感じです。
ペンチもスパナもニッパーもドライバーも工具箱に入ってますよね。
その工具箱を開けて使いたい工具を取り出すって過程が「Facadeを使う」ってことだと思えばいいと思うような気もしなくもないです。
「使うメリットは?」など詳しくはLaravelのファサードが全然わからなかったので自分なりに色々と調べた事をご覧ください。
##登場人物
1.Facadeにしたいクラスが書いてあるファイル
2.サービスプロバイダに登録するためのファイル (サービスプロバイダは後述)
3.Laravelにサービスプロバイダを読み込ませるconfig/app.php
4.登録したサービス(クラス)をうまい事呼び出せるようにするためのファイル
5.Viewに出力(画面に表示)させるためのroutes/web.phpファイル
##Facadeにしたいクラスが書いてあるファイルを自作
今回は簡単なFacadeを作っていこうと思います。
完成形としてはFriend::get
と打ち込むと「愛と勇気だけ」と出力されるものを作ります。
もっと便利なものを作りたい時は適宜応用してください。
ファイルを作る場所はどこでもいいのですが、私はapp/Services/MyFriend.php
としました。
(app/servicesというディレクトリはデフォルトでないので自分で作ってください。)
<?php
namespace App\Services;
class MyFriend{
public function get()
{
return "愛と勇気だけ";
}
}
##サービスプロバイダにMyFriend.phpを登録する
まずサービスとは要するに「クラス」のことです。
サービスプロバイダに登録というのは「クラスを一カ所に集めておく」ということで、サービスプロバイダというのは「クラスを一カ所に集めた集合場所」みたいな感じです。
(正確に言うと集合場所のことを「サービスコンテナ」と言って、コンテナから取り出して利用することをサービスプロバイダと言います。)
サービスプロバイダの登録方法と利用方法は、ざっくりいうと「(親玉のServiceProviderというクラスを引き継いだクラスの中で)app()->bind('a','class')
」とヘルパ関数を用いて書くとa
という名前で、class
を保存する、みたいに登録できます。
また利用方法は「(RouteやControllerの中で)app('a')」と書けば良きです。
(ヘルパ関数についてはLaravelのよく使うヘルパー関数7選!を参考にしてください。)
また、サービスコンテナ、サービスプロバイダの詳細についてはLaravel サービスコンテナの理解を深めるをお読み下さい。
さて、ではMyFriend.phpを登録してみましょう。
登録するための「サービスプロバイダに登録するためのファイル(MyFriendServicePrrovider.php)」というファイルを以下のコマンドを使って作ってきます。
php artisan make:provider MyFriendServiceProvider
そして作られたファイルのregisterメソッド中にサービスプロバイダに登録するという旨を書きます。
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class MyFriendServiceProvider extends ServiceProvider
{
public function register()
{
app()->bind('myfriend','App\Services\Myfriend'); //登録するという旨を追加
}
public function boot()
{
//
}
}
registerメソッドというのはLaravelが一気に読み込んでくれる場所です。
なので他のAuthServiceProvider.php
やAppServiceProvider.php
とかのregisterメソッドなども読み込んでいきます。
registerメソッド中でapp()->bind('myfriend','App\Services\Myfriend')
を読み込ませることによって
「myfriend
って言ったら、App/Services/Myfriend.php
にあるクラスを引き出してきてね」と書いたということですね。
##config/app.phpファイルに作ったサビプロを読ませる
もう面倒くさいのでサービスプロバイダはサビプロと言います。
コマンドから作ったapp/Provider/MyFriendServicePrrovider.php
ですが、そのままではLaravelは読んでくれません。
読み込んでもらうためには「読み込むサビプロ一覧」に名前を書く必要があります。
それがconfig/app.php
です。
以下のようにproviderの中に記述しておきましょう。
<?php
return [
//省略
'providers' => [
//省略
App\Providers\MyFriendServiceProvider::class,
]
これで
1.Laravelがconfig/app.php
から読み込むサビプロを識別する。
2.MyFriendServiceProvider.php
が読み込まれる。
3.myfriend
という名前でMyfriend.php
の中のMyFriendクラスが登録される。
という流れまで抑えられましたね。
さてサビプロ登録編が終わったので次は活用編です。
##サビプロを使ってみる。
では実際にroutes/web.phpからルートを通して表示させてみましょう。
一旦、「登場人物4.登録したサービス(クラス)をうまい事呼び出せるようにするためのファイル」は置いといてください。
<?php
use Illuminate\Support\Facades\Route;
Route::get('/WhoIsMyFriend',function(){
return app('myfriend')->get(); //->get()はMyFriendクラスのメソッド
});
そしてLocalhost:8000/WhoIsMyFriend
にアクセスしてみると…
**「愛と勇気だけ」**と表示されると思います!
これでファサードとは何かが分かったと思うのですが、おまけで後2工程やっていきましょう。
##ファサードっぽく呼び出す
「登場人物4.登録したサービス(クラス)をうまい事呼び出せるようにするためのファイル」であるapp/Facades/MyFriend.php
を作っていきます。(デフォルトではないので手打ちで作っていきましょう)
<?php
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
class MyFriend extends Facade{
protected static function getFacadeAccessor()
{
return 'myfriend';
}
}
これ何をしてるかというと…
いえ、多分見た方が早いです。
routes/web.php
を少し改良していきます。
<?php
use Illuminate\Support\Facades\Route;
Route::get('/WhoIsMyFriend',function(){
//return app('myfriend')->get(); //削除
return \App\Facades\MyFriend::get();; //追加
});
そしてLocalhost:8000/WhoIsMyFriend
にアクセスすると同じように**「愛と勇気だけ」**と表示されましたね。
つまり、自作したapp/Facades/MyFriend.php
ではサビプロに登録した名前をreturnすることで、呼び出し方をファサード風味にしてるんですね。
まぁいつものように詳しくはファサードの仕組みを簡単にまとめる【Laravel】をご覧ください。マジックメソッドとか使ってあれやこれややってます
。
これで皆が知ってるFacadeの形になりましたね。長かった…
ですが最後に
「こんな「\」記号なんて使わなかったよ!」
という声にお応えしてエイリアスの登録をしておきます。
エイリアスは先ほど出てきたconfig/app.php
の中で定義します。
<?php
return [
//省略
'aliases' => [
//省略
'MyFriend' => App\Facades\MyFriend::class,
]
これで
<?php
use Illuminate\Support\Facades\Route;
Route::get('/WhoIsMyFriend',function(){
//return app('myfriend')->get(); //削除
//return \App\Facades\MyFriend::get();; //削除
return MyFriend::get();; //追加
});
//愛と勇気だけ
見慣れた、「急に::を使ってあれやこれやする」あの形のFacadeができました。
##最後に
分からなくても一気に解決するのではなく、数学の方程式みたいにわからない部分をaと置いといて次に行った方が一周回って腹落ちする時が来ますよ~
そんな感じで絵ゆるりと見てください。
##参考文献
本文中のもの+
公式
Laravelのサービスプロバイダーの仕組みやメリットとは