回答:
このマニュアルでは、「コールバック」と「呼び出し可能」という用語を同じ意味で使用していますが、「コールバック」は従来、関数ポインタのように機能する文字列または配列値を指し、将来の呼び出しのために関数またはクラスメソッドを参照します。これにより、PHP 4以降、関数型プログラミングのいくつかの要素が可能になりました。フレーバーは次のとおりです。
$cb1 = 'someGlobalFunction';
$cb2 = ['ClassName', 'someStaticMethod'];
$cb3 = [$object, 'somePublicMethod'];
// this syntax is callable since PHP 5.2.3 but a string containing it
// cannot be called directly
$cb2 = 'ClassName::someStaticMethod';
$cb2(); // fatal error
// legacy syntax for PHP 4
$cb3 = array(&$object, 'somePublicMethod');
これは、呼び出し可能な値を一般的に使用する安全な方法です。
if (is_callable($cb2)) {
// Autoloading will be invoked to load the class "ClassName" if it's not
// yet defined, and PHP will check that the class has a method
// "someStaticMethod". Note that is_callable() will NOT verify that the
// method can safely be executed in static context.
$returnValue = call_user_func($cb2, $arg1, $arg2);
}
最新のPHPバージョンでは、上記の最初の3つの形式をとして直接呼び出すことができます$cb()
。上記すべてcall_user_func
をcall_user_func_array
サポートします。
参照:http : //php.net/manual/en/language.types.callable.php
注意事項/注意事項:
['Vendor\Package\Foo', 'method']
call_user_func
は参照による非オブジェクトの受け渡しをサポートしていないためcall_user_func_array
、以降のPHPバージョンでは、コールバックをvarに保存して直接構文を使用できます$cb()
。__invoke()
メソッドを持つオブジェクト(無名関数を含む)は「呼び出し可能」のカテゴリーに分類され、同じように使用できますが、私はこれらを従来の「コールバック」という用語に関連付けていません。create_function()
はグローバル関数を作成し、その名前を返します。これはラッパーでeval()
あり、代わりに無名関数を使用する必要があります。'someGlobalFunction'
確かに定義された関数であることを回答で指摘することは、Pythonプログラミングの読者に役立つでしょう。
PHP 5.3では、これを行うことができます。
function doIt($callback) { $callback(); }
doIt(function() {
// this will be done
});
最後にそれを行うための素晴らしい方法。コールバックは素晴らしいので、PHPへの素晴らしい追加です。
コールバックの実装はそのように行われます
// This function uses a callback function.
function doIt($callback)
{
$data = "this is my data";
$callback($data);
}
// This is a sample callback function for doIt().
function myCallback($data)
{
print 'Data is: ' . $data . "\n";
}
// Call doIt() and pass our sample callback function's name.
doIt('myCallback');
表示:データは:これは私のデータです
call_user_func()
そのため、動的に関数を呼び出してコールバックを実行できる構文がある場合に、なぜ人々が使いたいのかさえわかりません。仰るとおりです!
私が最近見つけた気の利いたトリックの1つは、PHPを使用create_function()
して、1回限りの使用のための匿名/ラムダ関数を作成することです。それはのようなPHPの機能のために便利ですarray_map()
、preg_replace_callback()
またはusort()
カスタム処理のためのその使用のコールバック。裏で行うように見えますが、eval()
それでもPHPを使用するための優れた関数型の方法です。
create_function()
ますか?
さて... 5.3が近づくと、すべてが良くなります。5.3を使用すると、クロージャーと匿名関数が取得されるからです。
呼び出しが有効であることを確認する必要があります。たとえば、特定の関数の場合は、その関数が存在するかどうかを確認する必要があります。
function doIt($callback) {
if(function_exists($callback)) {
$callback();
} else {
// some error handling
}
}
is_callable( $callback )
create_function
クラスの中で私のために働きませんでした。私は使用しなければなりませんでしたcall_user_func
。
<?php
class Dispatcher {
//Added explicit callback declaration.
var $callback;
public function Dispatcher( $callback ){
$this->callback = $callback;
}
public function asynchronous_method(){
//do asynch stuff, like fwrite...then, fire callback.
if ( isset( $this->callback ) ) {
if (function_exists( $this->callback )) call_user_func( $this->callback, "File done!" );
}
}
}
次に、使用するには:
<?php
include_once('Dispatcher.php');
$d = new Dispatcher( 'do_callback' );
$d->asynchronous_method();
function do_callback( $data ){
print 'Data is: ' . $data . "\n";
}
?>
[編集]欠落していた括弧を追加。また、コールバック宣言を追加しましたが、私はそれを好みます。
PHP < 5.4
との互換性を壊すことを気にしない人のために、型ヒントを使用してよりクリーンな実装にすることをお勧めします。
function call_with_hello_and_append_world( callable $callback )
{
// No need to check $closure because of the type hint
return $callback( "hello" )."world";
}
function append_space( $string )
{
return $string." ";
}
$output1 = call_with_hello_and_append_world( function( $string ) { return $string." "; } );
var_dump( $output1 ); // string(11) "hello world"
$output2 = call_with_hello_and_append_world( "append_space" );
var_dump( $output2 ); // string(11) "hello world"
$old_lambda = create_function( '$string', 'return $string." ";' );
$output3 = call_with_hello_and_append_world( $old_lambda );
var_dump( $output3 ); // string(11) "hello world"
create_function()
は、PHP 7.2.0で廃止されました。この機能に依存することはお勧めできません。