ITHACK
~ みんなのIT部門 ~

【PHP】無名関数(クロージャー) – 名前がない関数

PHPには無名関数と呼ばれる仕組みがあります。
別名でクロージャーと呼ばれ、関数名がない関数として知られています。

ここでは無名関数(クロージャー)について解説します。

  • 無名関数(クロージャー)

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

無名関数は名前の通り、関数名がない関数です。
構文は関数のように記述することができますが、実態はPHPにデフォルトで用意されているClosureクラスのインスタンスになります。

そのため、変数に代入したり、引数として与えることができます。

基本構文

無名関数には定義と実行の基本構文があります。

定義

function( $引数名 ) {
    // 処理・・・
};

基本的には関数と同じですが、無名関数は関数名を記述せず、ブロック({})の最後にセミコロン(;)が必要になります。

また、代入演算子で変数に代入できます。

$変数名 = function( $引数名 ) {
    // 処理・・・
};

実行

$変数名( $引数名 );

変数に無名関数が代入されている場合、変数に続いて丸括弧(())を記述することで無名関数を実行できます。

サンプルコード

無名関数を使ったサンプルコードをご覧ください。

<?php

$addition = function( $x, $y ) {
    return $x + $y;
};

echo $addition(3, 5)."\n";

?>
8

無名関数を使った2つの値を足し算するコードです。

各コードの概要は次の表をご覧ください。

行数 概要
3~5 無名関数を$additionに代入。
7 $additionに記憶された無名関数を実行し、出力。

$addition(3, 5)で無名関数を実行しており、戻り値として8が返ってきています。

無名関数を引数で与える

無名関数は引数で与えることができます。

次のサンプルコードをご覧ください。

<?php

function calculation($a, $b, $closure) {
    return $closure($a, $b);
}

$result1 = calculation(5, 7, function( $x, $y ) {
    return $x + $y;
});

$result2 = calculation(5, 7, function( $x, $y ) {
    return $x - $y;
});

echo "result1 = ".$result1."\n";
echo "result2 = ".$result2."\n";

?>
result1 = 12
result2 = -2

各コードの解説は次の表をご覧ください。

行数 概要
3~5 2つの値を計算するcalculation関数を定義。(計算方法は引数$closureに従う)
7~9 calculation関数を呼び出し、$result1に代入。引数の$closureには足し算を行う無名関数を渡す。
11~13 calculation関数を呼び出し、$result2に代入。引数の$closureには引き算を行う無名関数を渡す。
15~16 $result1と$result2を出力

7行目と11行目のcalculation関数の呼び出しでは、第3引数で無名関数を与えています。
実行結果からcalculation関数の処理ではそれぞれの無名関数の内容に従った計算を処理していることが分かります。

演習問題

問題1

会計の合計金額を計算するプログラムを作成してください。
なお、下記条件を満たすものとします。

  • 合計金額の計算式は『単価×個数』とする
  • 単価と個数は標準入力で与える
  • 合計金額を計算する処理は無名関数で行う(変数に記憶しておく)
$ php practice.php
単価 > 100
個数 > 5 
合計料金 : 500円
$ php practice.php
単価 > 1800
個数 > 7
合計料金 : 12600円

問題2

複数数値の一覧と合計値を出力するプログラムを作成してください。
なお、下記条件を満たすものとします。

  • 複数数値は標準入力で与える(空文字が入力されるまで)
  • 複数数値の一覧を出力する処理を行う無名関数を作成する
  • 複数数値の合計値を戻り値として返す処理を行う無名関数を作成する
  • execute関数を下記の次の仕様で作成する
    引数: 複数数値、クロージャー
    処理: クロージャーを呼び出し、引数に複数数値を与える
$ php practice.php
===  Input  ===
> 123
> 456
> 789
> 
=== Closure ===
123
456
789
total : 1368
$ php practice.php
===  Input  ===
> 1234
> 3456
> 5678
> 7890
> 
=== Closure ===
1234
3456
5678
7890
total : 18258

まとめ

無名関数(クロージャー)は関数名のない関数です。
その実態はClosureクラスのインスタンスとなるため、変数に代入したり、引数として与えることができます。