Laravelで使うクロージャー/Closure/無名関数

クロージャー、またの名を無名関数と言います。
初学者の方には理解しづらい概念なのでは無いでしょうか。
私もクロージャーを利用する機会はありますが、正しく理解せずに利用していました。

様々な記事で紹介されていますが、いまいち分かりづらいですよね…. 

おそらく、理解を難しくしている1番の原因は「何となく分かるが、何のために存在しているのか分からない」ということに尽きると思います。

今回は、クロージャーが何のために存在するのか。また、Laravelだとどのように使われているのかを紹介していきます。 少しでも、クロージャーのイメージを掴んで頂けたらと思います。

Q1. クロージャー(無名関数)とは

名称の通り無名関数です。名もなき関数。
ただの処理の塊です。

Q2. クロージャー(無名関数)の書き方

function( 引数 ){ 
//処理
};

この部分がクロージャー(無名関数)です。名が存在しません。

通常のLaravel関数であれば下記のように、hoge、piyoなどの関数名が付きます。が、クロージャーは名もなき処理の塊です。

private function hoge(){
//処理
}
private function piyo(){
//処理
}

Q3. クロージャーの利用用途

色々な使われ方をします。
が、そこを全て把握しようとすると理解を難しくすると思います。

ここでは、Laravelでよく利用されている使われ方を利用することによって、敢えて限定的な利用用途を紹介します。

Q3-1. Laravelでよく使われるクロージャーの利用用途

コールバックの処理に使われるのが、クロージャー(無名関数)の代表的な利用用途だと思います。

コールバック処理での、クロージャー利用用途を理解するとクロージャーの存在価値がよく分かると思います。

Q3-2. Laravelでコールバックで使われるクロージャー利用例

実際に、Laravelのコールバック処理内で利用されるクロージャーの利用例を紹介します。

例:Route
Route::get('/', function () {
     return view('welcome'); 
});

必ず利用するRouteの処理もクロージャーを利用しています。
Route::get( 第一引数 , 第二引数 ); という処理です。

  • 第一引数:
    • ルーティングの文字列
  • 第二引数:
    • ルーティングに応じた処理(viewを返す OR Controllerのメソッドを呼び出す) -> クロージャーの処理で記述
Routeの深堀り

Route::get( ); の処理は下記で記述されています。

// ディレクトリ
app/vendor/laravel/framework/src/Illuminate/Routing/Router.php

//メソッド
    /**
     * Register a new GET route with the router.
     *
     * @param  string  $uri
     * @param  array|string|callable|null  $action
     * @return \Illuminate\Routing\Route
     */
    public function get($uri, $action = null)
    {
        return $this->addRoute(['GET', 'HEAD'], $uri, $action);
    }

addRoute()に $uri, $actionが渡されています。
$action → クロージャー(無名関数)で渡している処理となっています。

addRoute をもう少し深掘る
//addRoute
    public function addRoute($methods, $uri, $action)
    {
        return $this->routes->add($this->createRoute($methods, $uri, $action));
    }

//createRoute
protected function createRoute($methods, $uri, $action)
{

    if ($this->actionReferencesController($action)) {
        $action = $this->convertToControllerAction($action);
    }

    $route = $this->newRoute(
        $methods, $this->prefix($uri), $action
    );

    if ($this->hasGroupStack()) {
        $this->mergeGroupAttributesIntoRoute($route);
    }

    $this->addWhereClausesToRoute($route);

    return $route;
}

こちらのRouterの処理を全てを理解する必要はありません。

抑えておきたいのは、Route::get( 第一引数 , 第二引数 )で引き渡した、クロージャーが、$actionとして、最終的に$routeインスタンスに代入され、その後の処理に続いていくということです。

このように、クロージャーは処理自体をコールバック処理の中に含めて渡していくために用いられるイメージを持つと、存在価値がイメージ掴みやすいかと思います。

Q3-3. Laravelでコールバックで使われるクロージャー処理を言語化すると…

イメージしやすくするために、敢えて 強引に言語化すると

  • 処理が途中まで決まっている(コールバック)処理
  • 処理の一部分だけ、利用者(プログラム記述者)が勝手に決めて、処理を渡して!
  • その渡す処理を クロージャー(無名関数)で渡して!

みたいな感じです。

Q4. クロージャーのまとめ

クロージャーの利用用途は幾つもありますが、今回はコールバック処理の中で利用されるクロージャーのみを紹介しました。
コールバック内での利用され方は、下記でした。

処理が途中まで決まっている(コールバック)処理
処理の一部分だけ、利用者(プログラム記述者)が勝手に決めて、処理を渡して!
その渡す処理を クロージャー(無名関数)で渡して!

ざっくりと、まとめると。

定形の処理の一部を、可変にして自由に利用させたい。
その可変部分の処理を名もなきクロージャー(無名関数)で記述して下さい。

という感じです。

イメージしやすくするために省略した部分もありますが、イメージを掴めたでしょうか?