初めに
タイトルの通りのことをソースコードを眺めているときに思ったのでそれについて調べたことをまとめた備忘録です。
Laravel
により提供されているIlluminate
配下のソースコードを眺めているときになんだこれ?って思ったのがきっかけです。
以下、なんだこれ?って思った処理のあるソースコード。
protected function resolve($name)
{
$config = $this->getConfig($name);
// ~~中略~~
$driverMethod = 'create'.ucfirst($config['driver']).'Driver';
if (method_exists($this, $driverMethod)) {
return $this->{$driverMethod}($name, $config); // ★
}
// ~~後略~~
}
★のところに注目してください。この部分の$this->{$driverMethod}($name, $config)
がなにをしているのかが疑問だったのでその疑問を解決すべく調べてみました。
この表記はどうやら可変関数というらしい
PHP は可変関数(variable functions)の概念をサポートします。 これにより、変数名の後に括弧が付いている場合、その値が何であろうと PHPは、同名の関数を探し実行を試みます。 この機能は、コールバック、関数テーブル等を実装するために使用可能です。
引用:PHP: 可変関数 - Manual
例えば、
function foo()
{
echo "Foooooo in foo()";
}
$method = "foo";
のようにfoo()
と、関数名と同じ名前の文字列を持つ$method
変数があったとします。
このとき$method()
のように、$method
の後ろに丸括弧を付けてみましょう。
するとPHPが自動で$method
の文字列と同名の関数を探し出して実行してくれます。これが可変関数という概念らしいです。
$method(); // "Foooooo in foo()"が出力される
それを踏まえてさっきのやつを見直してみる
以上で記事の主題は解決しました。ですが、せっかくなので先ほどのIlluminate/Auth/AuthManager.php
がなにをやっているのかを追えるとこまで追っていきましょう。
以下、再掲です。
protected function resolve($name)
{
$config = $this->getConfig($name);
// ~~中略~~
$driverMethod = 'create'.ucfirst($config['driver']).'Driver'; // 1.
if (method_exists($this, $driverMethod)) { // 2.
return $this->{$driverMethod}($name, $config); // 3.
}
// ~~後略~~
}
このメソッドが呼び出される状況を、
-
$name
には"web"という文字列 -
$config
にはgetConfig($name)
メソッドによって['driver' => 'session', 'provider' =>'users']
という連想配列
がそれぞれ代入される、というように仮定します。
それを踏まえて番号のついた行を詳しく見てみましょう。
1. の処理
$driverMethod = 'create'.ucfirst($config['driver']).'Driver'; // 1.
ucfirst()
という関数はPHP組み込みの関数で、引数がアルファベットの文字列なら頭文字を大文字に変換して返すという処理をしてくれます。
なので、$config['driver']
が"session"
であることを踏まえると、$driverMethod
には'createSessionDriver'
という文字列が代入されます。
2.の処理
if (method_exists($this, $driverMethod)) { // 2.
こちらも1. と同様にmethod_exists()
というPHP組み込みの関数が使われています。
これは第1引数に指定したクラスオブジェクトに、第2引数で指定した名前のメソッドが定義されているかを真偽値で返してくれる関数になります。
それを踏まえると2. の処理はAuthManager
クラスにcreateSessionDriver
という名前のメソッドが存在するか、という条件分岐を行っている処理だということが分かりました。
3.の処理
return $this->{$driverMethod}($name, $config); // 3.
3.の処理において先ほど説明した可変関数の概念が使われています。
いままで説明してきたことを踏まえると、この処理は$this->createSessionDriver($name, $config);
であるということが明らかとなりました。
以下、本題からそれるので簡単な説明になりますが、このcreateSessionDriver()
によってLaravelではセッションによる認証機能の提供が行われることになります。
よく見かける、
Auth::user();
といったAuth
ファサードによるユーザー情報の取得処理にも、このcreateSessionDriver()
から提供されている認証機能が使われています。
終わりに
Laravelのファサードの実体を追っている中で疑問に思ったことをまとめてみました。
次回はファサードの実体がどこにあるかを追ってみて、その調査結果をまとめてみたいと思います。