function_exists だと無記名関数はチェックできない
<?php /** * @param: $callback コールバック関数 */ function func($callback) { var_dump( function_exists($callback) ); if( function_exists( $callback ) ) { call_user_func( $callback ); } else { echo '関数がないよ。'; } } function destroyer() { echo '響だよ'; } // 関数名を文字列で渡すのはOK func('destroyer'); // => 'bool(true) 響だよ' // 変数に関数名を文字列で代入してもOK $myFunc = 'destroyer'; func($myFunc); // => 'bool(true) 響だよ' // 無記名関数は実行されない func( function() { echo '響だよ'; } ); // => NULL 関数がないよ。
function_exists
function_exists — 指定した関数が定義されている場合に TRUE を返す
無記名関数は関数として定義されてないので、function_exists()
がNULL
になるので、function_exists()
でcallback関数のチェックをしている場合は実行されない。
is_callable でチェックする
is_callable
is_callable — 引数が、関数としてコール可能な構造であるかどうかを調べる
<?php /** * @param: $callback コールバック関数 */ function func($callback) { var_dump( is_callable($callback) ); if( is_callable( $callback ) ) { call_user_func( $callback ); } else { echo '関数がないよ。'; } } function destroyer() { echo '響だよ'; } // 関数名を文字列で渡すのはOK func('destroyer'); // => 'bool(true) 響だよ' // 変数に関数名を文字列で代入してもOK $myFunc = 'destroyer'; func($myFunc); // => 'bool(true) 響だよ' // 無記名関数でもOK func( function() { echo '響だよ'; } ); // => bool(true) 響だよ
PHP5.4以降なら コールバック関数を実行する関数の引数にタイプヒンティングを付けておくと、関数以外を渡すとエラーを返せるようになる。
<?php /** * @param: $callback コールバック関数 */ function func(callable $callback) { // ※ 関数でない場合はエラーになるので if( is_callable ) でチェックする意味は無い call_user_func( $callback ); } // 存在しない関数名を渡す func( 'myFunc' ); //=> PHP Catchable fatal error: Argument 1 passed to func() must be callable, ...
コールバック関数に引数を使いたい
call_user_func()
では第2引数以降にパラメーター追加していって渡すことができる。
mixed call_user_func ( callable $callback [, mixed $parameter [, mixed $... ]] )※ call_user_func() のパラメータは 参照渡しではないことに注意
<?php /** * @param: $callback コールバック関数 * @param: $a1, $2, $a3 ... コールバック関数に渡す引数 * ※ 引数の数が合わないと Warning になるので注意が必要 */ function func(callable $callback, $a1, $a2, $a3) { call_user_func( $callback, $a1, $a2, $a3 ); } function destroyer($type, $number, $name) { echo "{$type}型 {$number}番艦 {$name}だよ"; } func('destroyer', '暁', '一', '暁'); // => 暁型 一番艦 暁だよ func( function($type, $number, $name) { echo "{$type}型 {$number}番艦 {$name}だよ"; }, '暁', '二', '響'); // => 暁型 二番艦 響だよ
パラメータが可変になるなら、第2引数の配列が展開されて、コールバックに渡されるのでcall_user_func_array
の方が便利そう。
mixed call_user_func_array ( callable $callback , array $param_arr )
<?php /** * @param: $callback コールバック関数 * @param: $params(Array) コールバック関数に渡す引数の配列 */ function func(callable $callback, $params = []) { call_user_func_array( $callback, $params ); } function destroyer($type, $number, $name) { echo "{$type}型 {$number}番艦 {$name}だよ"; } func('destroyer', ['暁', '一', '暁']); // => 暁型 一番艦 暁だよ func( function($type, $number, $name) { echo "{$type}型 {$number}番艦 {$name}だよ"; }, ['暁', '二', '響']); // => 暁型 二番艦 響だよ
[参考]
- PHPでコールバック関数を利用する - Qiita
- 【PHP】タイプヒンティング - Qiita
- http://php.net/manual/ja/function.function-exists.php
- http://php.net/manual/ja/function.is-callable.php
- http://php.net/manual/ja/function.call-user-func.php
- http://php.net/manual/ja/function.call-user-func-array.php
- php - Passing parameters with call_user_func? - Stack Overflow
タミヤ 1/35 ミリタリーミニチュアシリーズ No.325 ドイツ陸軍 重駆逐戦車 エレファント プラモデル 35325
- 発売日: 2012/07/21
- メディア: おもちゃ&ホビー