現在の言語: 日本語

戻る

call_user_func
コールバック関数

[コールバック関数について]
PHPのcallableとは、「関数として呼び出すことができるデータ型」を表す型ヒントです。
関数が引数として別の関数を受け取る(高階関数)際などに、
「実行可能なものだけを許可する」ために使用されています。
※PHP 5.4から使用可能

call_user_func
call_user_func関数を使用して普通の関数名を文字列で渡すことで
コールバックを指定できます。

[サンプル]

copy
/*
function func1()
{
	echo "func1 execute".PHP_EOL;
}
*/
class test1
{
	//クラス内のメソッドを実行するケース
	function test1()
	{
/*
Fatal error:  Uncaught TypeError: call_user_func(): Argument #1 ($callback) must be a valid callback, function "func1" not found or invalid function name
*/
		//call_user_func("func1");
		call_user_func([$this, "func1"]);//func1 execute
		call_user_func("test1::func2");//static func2 execute
	}

	private function func1()
	{
		echo "func1 execute".PHP_EOL;
	}
	private static function func2()
	{
		echo "static func2 execute".PHP_EOL;
	}
	//戻り値を実行するケース
	function test2()
	{
		$num1 = 10;
		$num2 = 20;
		//引数を指定するケース
		$result = call_user_func([$this, "func3"], $num1, $num2);
		echo "result:$result".PHP_EOL;//result:30
	}
	private function func3(int $num1, int $num2):int
	{
		return $num1 + $num2;
	}
	function test3()
	{
		$num1 = 10;
		$num2 = 20;
		//引数を指定するケース
		//Warning:  test1::func4(): Argument #2 ($num2) must be passed by reference, value given
		//$result = call_user_func([$this, "func4"], $num1, $num2);
	}
	private function func4(int $num1, int &$num2)//ここで参照渡しを設定しておく
	{
		$num2++;
		return $num1 + $num2;
	}
	//コールバック関数を引数にしたケース
	function test4()
	{
		 call_user_func([$this, "func5"], function($str) {
            echo "Callback received: $str";
        });
		//Callback received: func5
	}
	private function func5(callable $callback):void
	{
		$callback("func5");
	}
}
echo "<pre>";
$cls1= new test1();
$cls1->test1();
$cls1->test2();
$cls1->test3();
$cls1->test4();
echo "</pre>";
copy
/*
function func1()
{
echo "func1 execute".PHP_EOL;
}
*/
class test1
{
	// Execute a method within a class
	function test1()
	{
		/*
		Fatal error: Uncaught TypeError: call_user_func(): Argument #1 ($callback) must be a valid callback, function "func1" not found, or invalid function name
		*/
		/call_user_func("func1");
		call_user_func([$this, "func1"]);//func1 execute
		call_user_func("test1::func2");//static func2 execute
	}
	
	private function func1()
	{
		echo "func1 execute".PHP_EOL;
	}
	private static function func2()
	{
		echo "static func2 execute".PHP_EOL;
	}
	// Execute the return value
	function test2()
	{
		$num1 = 10;
		$num2 = 20;
		//Argument specification case
		$result = call_user_func([$this, "func3"], $num1, $num2);
		echo "result:$result".PHP_EOL;//result:30
	}
	private function func3(int $num1, int $num2):int
	{
		return $num1 + $num2;
	}
	function test3()
	{
		$num1 = 10;
		$num2 = 20;
		//Argument specification case
		//Warning: test1::func4(): Argument #2 ($num2) must be passed by reference, value given
		//$result = call_user_func([$this, "func4"], $num1, $num2);
	}
	private function func4(int $num1, int &$num2)//Set up reference passing here
	{
		$num2++;
		return $num1 + $num2;
	}
	//Callback function argument
	function test4()
	{
		call_user_func([$this, "func5"], function($str) {
			echo "Callback received: $str";
		});
		//Callback received: func5
	}
	private function func5(callable $callback):void
	{
		$callback("func5");
	}
}
echo "<pre>";
$cls1= new test1();
$cls1->test1();
$cls1->test2();
$cls1->test3();
$cls1->test4();
echo "</pre>";

test1
call_user_func([$this, "func1"]);
クラス内で関数を指定する場合は配列にクラスと関数名を指定します。

call_user_func("test1::func2");
staticメソッドを実行する方法です。

test2
$result = call_user_func([$this, "func3"], $num1, $num2);
実行する関数に引数がある場合は上記のように配列のあとにカンマ区切りで変数を実装します。
また
$result = call_user_func(
のようにすることで、戻り値を取得することができます。

test3
call_user_funcは参照渡しが使えません。
これは、この関数(call_user_func)の内部使用にあります。
call_user_funcは内部的に全て引数を値渡しで受け取るように設定しているためです。
そのため、
$result =call_user_func([$this, "func4"], $num1, $num2);
のfunc4を実行する際、func4に参照渡しがあるため
Warning: test1::func4(): Argument #2 ($num2) must be passed by reference, value given
というエラーが発生します。

test4
引数にする場合は
[$this, "func5"], function($str)
のように[]の後にコールバック関数を実装します。
この例ではfunctionのコールバック関数を実行できます。


戻る

著作権情報
ホームページおよプリ等に掲載されている情報等については、いかなる保障もいたしません。
ホームページおよびアプリ等を通じて入手したいかなる情報も複製、販売、出版または使用させたり、
または公開したりすることはできません。
当方は、ホームページおよびアプリ等を利用したいかなる理由によっての障害等が発生しても、
その結果ホームページおよびアプリ等を利用された本人または他の第三者が被った損害について
一切の責任を負わないものとします。