The documentation is a little confusing, and with the recent OO changes it adds a little more to the confusion.
I was curious whether you could pass an object through the user func, modify it in that callback and have the actual object updated or whether some cloning was going on behind the scenes.
<?php
class Test
{
var $sValue = 'abc';
function testing($objTest)
{
$objTest->sValue = '123';
}
}
$obj = new Test();
call_user_func(array($obj, 'testing'), $obj);
var_dump($obj);
?>
This works as expected: The object is not cloned, and $sValue is properly set to '123'. With the OO changes in PHP 5, you don't need to do "function testing(&$objTest)" as it is already passed by reference.
本ドキュメントにおける疑似的な型および変数
mixed
mixed は、引数に多様な型 (全てである必要はない) を使うことができることを示します。
例えば gettype() 関数は全ての PHP の型を受け入れるのに対し、 str_replace() は文字列と配列のみを受け入れます。
callback
call_user_func() や usort() 等の関数は、ユーザが定義するコールバック関数を引数として受け入れます。 コールバック関数は、単純な関数だけでなく、オブジェクトのメソッド あるいはクラスの静的メソッドであってもかまいません。
PHP 関数はその名前を単に文字列として渡されます。 どのようなビルトインまたはユーザ定義の関数も渡すことができます。 ただし、 array(), echo(), empty(), eval(), exit(), isset(), list(), print() あるいは unset() はコールバックとしては使用できないことに注意しましょう。
オブジェクトのインスタンスを渡すための方法の 1 つは、 オブジェクトを 0 番目の要素、 メソッド名を 1 番目の要素として含む配列を渡すことです。
静的なクラスメソッドの場合、 0 番目の要素としてオブジェクトを渡す代わりにクラス名を渡すことにより、 オブジェクトのインスタンスを作成せずに渡すことができます。
一般的なユーザ定義関数とは異なり、create_function() では無名コールバック関数を作成することができます。PHP 5.3.0 以降は、 クロージャ を callback パラメータに渡せるようになりました。
例1 コールバック関数の例
<?php
// コールバック関数の例
function my_callback_function() {
echo 'hello world!';
}
// コールバックメソッドの例
class MyClass {
static function myCallbackMethod() {
echo 'Hello World!';
}
}
// タイプ 1: 単純なコールバック
call_user_func('my_callback_function');
// タイプ 2: 静的クラスメソッドのコール
call_user_func(array('MyClass', 'myCallbackMethod'));
// タイプ 3: オブジェクトメソッドのコール
$obj = new MyClass();
call_user_func(array($obj, 'myCallbackMethod'));
// タイプ 4: 静的クラスメソッドのコール (PHP 5.2.3 以降)
call_user_func('MyClass::myCallbackMethod');
// タイプ 5: 相対指定による静的クラスメソッドのコール (PHP 5.3.0 以降)
class A {
public static function who() {
echo "A\n";
}
}
class B extends A {
public static function who() {
echo "B\n";
}
}
call_user_func(array('B', 'parent::who')); // A
?>
例2 クロージャを使用するコールバックの例
<?php
// クロージャ
$double = function($a) {
return $a * 2;
};
// 数値の範囲
$numbers = range(1, 5);
// ここでクロージャをコールバックとして使用し、
// 指定した範囲の各要素の 2 倍の値を計算します
$new_numbers = array_map($double, $numbers);
print implode(' ', $new_numbers);
?>
上の例の出力は以下となります。
2 4 6 8 10
注意: PHP4 では、実際のオブジェクトを指すコールバックを作成するには 参照を使用する必要があります。そのコピーを使用してはいけません。 詳細は 参照についての説明 を参照ください。
void
返り値の型が void である場合は、 返り値に意味がないことを表します。パラメータ一覧で void が使用されている場合は、 その関数がパラメータを受け付けないことを表します。
...
関数のプロトタイプ宣言における $... は、 …など を表します。 この変数名を用いるのは、たとえば任意の数の引数を取りうる関数などです。
本ドキュメントにおける疑似的な型および変数
30-Aug-2009 01:20
12-Jun-2009 09:44
I noticed two important thing about putting callbacks into an arg list when calling a function:
1. The function to which the callback refers must be defined earlier in the source stream. So for example:
function main() {...; usort($array, 'sortfunction'); ... }
function sortfunction($a, $b){ return 0; }
Will NOT work, but this will:
function sortfunction($a, $b){ return 0; }
function main() {...; usort($array, 'sortfunction'); ... }
2. It's not really just a string. For example, this doesn't work:
usort($array, ($reverse?'reversesorter':'forwardsorter'));
I found these two discoveries quite counterintuitive.
20-Apr-2009 07:19
An example with PHP 5.3 and lambda functions
<?php
array_map (function ($value) {
return new MyFormElement ($value);
}, $_POST);
?>
24-May-2007 02:44
The mixed pseudotype is explained as meaning "multiple but not necessarily all" types, and the example of str_replace(mixed, mixed, mixed) is given where "mixed" means "string or array".
Keep in mind that this refers to the types of the function's arguments _after_ any type juggling.
09-Feb-2007 07:44
Parent methods for callbacks should be called 'parent::method', so if you wish to call a non-static parent method via a callback, you should use a callback of
<?
// always works
$callback = array($this, 'parent::method')
// works but gives an error in PHP5 with E_STRICT if the parent method is not static
$callback array('parent', 'method');
?>
01-Feb-2007 07:15
To recap mr dot lilov at gmail dot com's comment: If you want to pass a function as an argument to another function, for example "array_map", do this:
regular functions:
<?
array_map(intval, $array)
?>
static functions in a class:
<?
array_map(array('MyClass', 'MyFunction'), $array)
?>
functions from an object:
<?
array_map(array($this, 'MyFunction'), $array)
?>
I hope this clarifies things a little bit
