[PHP] 匿名関数(ラムダ式)とクロージャ(closure)


Study / PHP    作成日付 : 2020/02/04 03:00:00   修正日付 : 2020/02/04 03:00:00

こんにちは。明月です。


今回はphpの匿名関数(ラムダ)とクロージャに関して調べてみました。

匿名関数は既存phpで宣言した「function methodname($param)」の形じゃなく、「function($param)」という関数名がないことです。関数名がないというのは一回性の関数で「javascript」とコールバック関数とにみたいな流れの関数です。

<?php
  function runTest($func) {
    //$funcが関数の可否をチェックする。(javascriptでtypeof 変数 === "function"と同じ意味)
    if (is_callable($func)) {
      // 関数を実行してパラメータの10と5を入れる。
      return $func(10, 5);
    }
    return 0;
  }
  // 匿名関数でrunTest関数に関数を入れました。
  $add = runTest(function ($a, $b) {
    // 上のところで「10」と「5」のパラメータを渡したので「$a」、「$b」は「10」と「5」です。
    // 10と5を足すと結果は15です。
    return $a + $b;
  });
  // 匿名関数でrunTest関数に関数を入れました。
  $subtract = runTest(function ($a, $b) {
    // 上のところで「10」と「5」のパラメータを渡したので「$a」、「$b」は「10」と「5」です。
    // 10から5を引くと結果は5です。
    return $a - $b;
  });
?>
<!DOCTYPE html>
<html>
  <head><title>title</title></head>
  <body>
    <!-- $addの結果は「15」です。-->
    add : <?=$add?>
    <br />
    <!-- $subtractの結果は「5」です。-->
    subtract : <?=$subtract?>
  </body>
</html>


上の例をみればrunTest関数に2つのメソッド名がないメソッドを渡します。この関数では「$add」と「$substract」に結果を渡すための一回性の関数です。


クロージャとは「java」と「C#」、「javascript」のクロージャと同じ概念です。クロージャと言うのは関数内部じゃないところで宣言した変数を関数の中で使えることです。

実際にメモリ上では別のメモリ領域なので共有ができないですが、ソース上でメモリを共有するような機能になっています。

<?php
  $message = 'hello';
  // lambda式(匿名関数)
  $example1 = function () {
    var_dump($message);
  };
  // lambda式(匿名関数)
  // クロージャ機能を使うようには「use」で$message変数を使うと宣言する。
  $example2 = function () use ($message) {
    var_dump($message);
  };
  // 関数実行!
  $example1();
  $example2();
?>
<!DOCTYPE html>
<html>
  <head><title>title</title></head>
  <body></body>
</html>


上の例をみれば$message変数に「hello」という値を入力しました。各匿名関数「$example1」と「$example2」を作成しました。

$example1の関数では「$message」変数を参照するとエラーが発生します。エラー内容は宣言してない変数使用ということになっています。

なぜなら$messageの変数は$example1関数外で宣言したものからです。でも、$example2では$messageを使いますね。

useキーワードを利用して関数外の変数を使えるようにしたからです。

link - https://www.php.net/manual/en/functions.anonymous.php

link - https://www.php.net/closure

最新投稿