0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【PHP/Laravel】無名関数を理解する

0
Posted at

Laravelを学習していると、こんなコードをよく見かけます。

Route::get('/mypage', function () {
    return 'マイページ';
});

最初に見たとき、

function はあるけど、関数名がないのはなぜ?

となりました。
今回は、この 無名関数(Closure) について整理します。

無名関数とは

普通の関数には名前があります。

function sayHello()
{
    return 'こんにちは';
}

呼び出すときは

sayHello();

一方で、無名関数は名前がありません。

function () {
    return 'こんにちは';
}

その名の通り、
名前のない関数 = 無名関数です。

PHPでは、このような無名関数は Closure(クロージャ)
といいます。

Laravelではどこで使われる?

LaravelのRouteでよく登場します。

Route::get('/hello', function () {
    return 'こんにちは';
});

見やすくすると、

Route::get(
    '/hello',

    function () {
        return 'こんにちは';
    }
);

Laravelに、
GET /hello にアクセスされたら、この処理を実行してね
関数そのものを渡しているイメージです。

ゲームで考えると

普通の関数は、
名前付きの技です。

function slash()
{
    return 'アバンストラッシュ';
}
slash();

「アバンストラッシュ」という名前を指定して使えます。

無名関数は、名前を付けていない技
のようなもので、

$skill = function () {
    return '謎の攻撃!';
};

変数に入れれば、

$skill();

で実行できます。

無名関数(Closure)の重要ポイント

無名関数には、外側にある変数を持ち込めます。

そのときに使うのが、
useです。

例えば、

$enemy = 'ドラゴン';

$attack = function () use ($enemy) {
    return $enemy . 'を攻撃!';
};

実行
echo $attack();

結果は、

ドラゴンを攻撃!

になります。

なぜuseが必要なの?

無名関数の { } の中は、基本的に外側とは別の範囲です。

そのため、

$enemy = 'ドラゴン';

$attack = function () {
    return $enemy . 'を攻撃!';
};

と書いても、外側の $enemy をそのまま使うことはできません。
そこで、use ($enemy)と書くことによって使うことができます。

$attack = function () use ($enemy) {
    return $enemy . 'を攻撃!';
};

意味としては、
外側にある $enemy を、この関数の中にも持ってきて
という感じです。

functionの引数とuseは何が違う?

$enemy = 'ドラゴン';

$attack = function ($weapon) use ($enemy) {
    return $weapon . 'で' . $enemy . 'を攻撃!';
};

実行

echo $attack('剣');

結果

剣でドラゴンを攻撃!

このコードでは、
function ($weapon)と、use ($enemy)
では、値の入ってくるタイミングが違います。

$weapon

function ($weapon)

これは、関数を実行するときにもらう値です。

$attack('剣');

この '剣'$weapon に入ります。

$enemy

use ($enemy)

これは、関数の外側から持ち込む値です。

$enemy = 'ドラゴン';

という情報を、無名関数の中でも使えるようにしています。

ゲームっぽくすると、

$weapon
→ 技を使う瞬間にもらう武器

$enemy
→ 技を作るときに覚えておく敵

となります。

function ($weapon) use ($enemy)

武器は発動するときにもらう
敵の情報は事前に持っておくというイメージです。

Laravelでもuseはよく登場する

例えばEloquentの whereHas

$status = 'published';

$users = User::whereHas('posts', function ($query) use ($status) {
    $query->where('status', $status);
})->get();

それぞれ、
$query
→ Laravel側から渡される

$status
→ 外側から自分で持ち込む

という違いがあります。

これを理解すると、LaravelのClosureがかなり読みやすくなりました。

普通の関数と無名関数、どっちを使う?

用途によって使い分けます。

普通の関数・メソッド

何度も使う処理や、名前を付けた方が分かりやすい処理に向いています。

function attack()
{
    return '攻撃!';
}

無名関数・Closure

その場所でだけ使う短い処理に向いています。

Route::get('/hello', function () {
    return 'こんにちは';
});

LaravelのRouteのように、
この場でこの処理だけ実行したい
という場合に便利です。

まとめ

短くてその場だけ使う
→ Closure

何度も使う
→ 普通の関数・メソッド

Routeの処理が大きくなる
→ Controllerへ分ける

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?