PHPコールバック関数入門

# *Callable*

PHPの要素で関数として呼び出すことができるものを***コールバック***または ***callable*** といいます。

参考：[PHP: コールバック / Callable - Manual](https://www.php.net/manual/ja/language.types.callable.php)

本記事のタイトルにもあるとおり、***コールバック関数***といわれることもあるようです（実際 [PHP マニュアル](https://www.php.net/manual/ja/index.php)にも書かれています）。

無用な混乱をさけるため、本記事では呼び方を ***callable*** で統一することにします。

# Examples

説明を読んだだけでは理解できないと思いますので、*callable* の例をたくさんみていくことにしましょう。

## 例１

```php:PHP
function hello() {
    echo 'こんにちは。';
}

echo is_callable('hello') . PHP_EOL;

call_user_func('hello');
```

```terminal:result
1
こんにちは。
```

５行目の`is_callable`は、引数が *callable* であるかどうかを調べてくれる関数です。

>`is_callable` — 引数が、関数としてコール可能な構造であるかどうかを調べる
>
>[PHP: is_callable - Manual](https://www.php.net/manual/ja/function.is-callable.php)

引数が *callable* なら`true`を、 そうでなければ`false`を返します。
また、`echo true`は`1`を出力し`echo false`は何も出力しません。

上記の例では`1`が出力されていますので、`is_callble`の引数である文字列`hello`は *callable* であることがわかりました。
*callable* であるということは、文字列`hello`を関数として呼び出せるということです。

実際に、７行目で`call_user_func`という関数をつかって *callable* である文字列`hello`を関数として呼び出しています。

>`call_user_func` — 最初の引数で指定したコールバック関数をコールする
>
>[PHP: call_user_func - Manual](https://www.php.net/manual/ja/function.call-user-func)

`こんにちは。`と出力されていますので、１〜３行目で定義されている関数`hello`が呼び出されたことがわかりますね。

一般に、関数`foo`が定義されているとき文字列`foo`は *callable* となります。
このとき文字列`foo`を`call_user_func`にわたすことによって、関数`foo`を呼び出すことができます。


## 例２

```php:PHP
function hello() {
    echo 'こんにちは。';
}

echo is_callable(hello) . PHP_EOL;

call_user_func(hello);
```

```:
PHP Warning:  Use of undefined constant hello - assumed 'hello' (this will throw an Error in a future version of PHP) in ...
PHP Warning:  Use of undefined constant hello - assumed 'hello' (this will throw an Error in a future version of PHP) in ...
```

今回はエラーが出てしまいました。

エラーメッセージをよく読むと`Use of undefined constant hello - assumed 'hello'`と書かれています。
これは「定義されていない定数`hello`をつかっているようだけど、それは文字列`hello`のことじゃないか？」という意味です。

例１の５行目と７行目では、`hello`を二つのシングルクォーテーション（`''`）でかこむことによって、それが文字列であることを表していました。

今回の例では、シングルクォーテーションでかこむことをしなかったため、`hello`は定数として解釈されます。
このとき PHP は定数`hello`の値を関数にわたそうとします。
ところが定数`hello`は定義されていませんので、PHP はたいへん狼狽し、エラーメッセージを吐き、森へ帰ってしまったというわけです（？）。

>PHP 関数はその名前を単に文字列として渡します。
>
>[PHP: コールバック / Callable - Manual](https://www.php.net/manual/ja/language.types.callable.php)


## 例３

```php:PHP
function sum($int1, $int2) {
    return $int1 + $int2;
}

echo is_callable('sum') . PHP_EOL;

echo call_user_func_array('sum', [2, 5]);
```

```terminal:result
1
7
```

１〜３行目で定義されている関数`sum`は、二つの数値をうけとって、それらの和を返すというものです。
これを実行するためには`sum(2, 5)`のように二つの引数を指定する必要があります。

このような場合でも、文字列`sum`自体は *callable* です。
これは５行目の命令によって`1`が出力されていることからわかります。

さて、文字列`sum`が *callable* だということは、文字列`sum`を関数として呼び出せるということです。
`sum`のような引数を必要とする関数を *callable* によって呼び出したいときは、`call_user_func_array`という関数をつかいます。

>`call_user_func_array` — パラメータの配列を指定してコールバック関数をコールする
>
>[PHP: call_user_func_array - Manual](https://www.php.net/manual/ja/function.call-user-func-array)

第一引数には *callable* を、第二引数には呼び出される関数にわたしたい式を配列にしたものを指定します。

７行目では、`call_user_func_array`の第一引数には *callable* である文字列`sum`を、第二引数には配列`[2, 5]`を指定しました。
これによって関数`sum`が呼び出され、関数`sum`の第一引数には`2`が、第二引数には`5`がわたされます。
このとき関数`sum`は`2`と`5`の和である`7`を返しますので、この`7`が`echo`されて`7`が出力されたというわけです。

<details><summary>**余談・・**</summary>
<div>
つぎのコードは今回の例の７行目を`echo call_user_func('sum');`にとりかえたものです。

```php:PHP
function sum($int1, $int2) {
    return $int1 + $int2;
}

echo is_callable('sum') . PHP_EOL;

echo call_user_func('sum');
```

これを実行すると、もちろんエラーが出るのですが、このときのエラーメッセージはつぎのようになります。

```terminal:result
PHP Fatal error:  Uncaught ArgumentCountError: Too few arguments to function sum(), 0 passed in ... and exactly 2 expected in ......
```

「関数`sum`にわたす引数が少なすぎるよ！」といわれています。
ということは、関数`sum`の呼び出し自体は問題なく行われたということです。

先ほどみたとおり、文字列`sum`自体は *callable* でした。
ですので、`call_user_func`の引数に文字列`sum`を指定してあげれば、関数`sum`を呼び出すこと自体は問題なくできるというわけです。

</div>
</details>

## 例４

```php:PHP
$hello = function () {
  echo 'こんにちは。';  
};

echo is_callable($hello) . PHP_EOL;

call_user_func($hello);
```

```terminal:result
1
こんにちは。
```

１〜３行目で、変数`hello`に無名関数を代入しています。

無名関数は *callable* です。
これは５行目の命令によって`1`が出力されていることからわかります。

>一般的なユーザー定義関数とは異なり、 無名関数 もパラメータとして渡せます。
>
>[PHP: コールバック / Callable - Manual](https://www.php.net/manual/ja/language.types.callable.php)

７行目では、`call_user_func`に変数`hello`の値である無名関数をわたすことによって、その無名関数自身を呼び出しています。

<details><summary>**ちなみに・・**</summary>
<div>

```php:PHP
$hello = function () {
  echo 'こんにちは。';  
};

var_dump($hello);
```

```:result
object(Closure)#1 (0) {
}
```

無名関数はPHPが用意している`Closure`という特別なクラスのインスタンスとして実現されています。

>無名関数の実装には Closure クラスを使っています。
>
>[PHP: 無名関数 - Manual](https://www.php.net/manual/ja/functions.anonymous.php)

</div>
</details>


## 例５

```php:PHP
class Player {
    private $name;
    
    public function __construct($name) {
        $this->name = $name;
    }
    
    public function getname() {
        return $this->name;
    }
}

$ichiro = new Player('イチロー');

echo is_callable([$ichiro, 'getname']) . PHP_EOL;

echo call_user_func([$ichiro, 'getname']);
```

```:result
1
イチロー
```

１〜１０行目で、`Player`クラスを定義しています。このクラスのなかで`getname`というメソッドを定義しました。
つづく１２行目で`Player`クラスのインスタンスを作成し、変数`ichiro`に代入しています。

このとき、配列`[$ichiro, 'getname']`は *callable* です。
この配列を`call_user_func`の引数に指定することで、変数`ichiro`に代入された`Player`クラスのインスタンスの`getname`メソッドを呼び出すことができます。

>オブジェクトのインスタンスを渡すには配列を使います。 配列の 0 番目の要素にオブジェクトを、 そして 1 番目の要素にメソッド名を指定します。
>
>[PHP: コールバック / Callable - Manual](https://www.php.net/manual/ja/language.types.callable.php)

`イチロー`と出力されていることから、所期のメソッドが呼び出されたことがわかりますね。


## 例６

```php:PHP
class Car {
    public static function honk() {
        echo 'ビッビー';
    }
}

echo is_callable(['Car', 'honk']) . PHP_EOL;

call_user_func(['Car', 'honk']);
```

```:result
1
ビッビー
```

１〜５行目で、`Car`クラスを定義し、そのなかで`honk`という静的メソッドを定義しました。

このとき、配列`['Car', 'honk']`は *callable* です。
この配列を`call_user_func`の引数に指定することで、`Car`クラスの静的メソッド`honk`を呼び出すことができます。

>静的なクラスメソッドの場合、オブジェクトのインスタンスは不要です。 0 番目の要素として、オブジェクトのかわりにクラス名を指定します。
>
>[PHP: コールバック / Callable - Manual](https://www.php.net/manual/ja/language.types.callable.php)


## 例７

```php:PHP
class Car {
    public static function honk() {
        echo 'ビッビー';
    }
}

echo is_callable('Car::honk') . PHP_EOL;

call_user_func('Car::honk');
```

```:result
1
ビッビー
```

クラスの定義は例６とおなじです。

例６では、配列`['Car', 'honk']`が *callable* であることをたしかめました。
今回の例は、文字列`Car::honk`もまた *callable* であることを表しています。

>'ClassName::methodName' 形式で指定することもできます。
>
>[PHP: コールバック / Callable - Manual](https://www.php.net/manual/ja/language.types.callable.php)

クラスの静的メソッドを *callable* として表現する方法は二種類あるということですね。

# おしまい

*callable* の例をたくさんみてきました。
これで *callable* とは何なのか、多少なりとも理解が深まったと思います。

また、本記事では説明が不十分な箇所も多々あるかと思います。
疑問に思うところがあったら、適宜 [PHP マニュアル](https://www.php.net/manual/ja/index.php)等を参照してください。

最後まで読んでいただき、ありがとうございました。

<img width="400" src="https://pbs.twimg.com/media/B09fqIUIQAA7Tai.jpg">