百科狗-知识改变命运!
--

call_user_func_array() - php 选项信息函数

乐乐1年前 (2023-11-21)阅读数 30#技术干货
文章标签回调

call_user_func_array()

(PHP 4 >= 4.0.4, PHP 5, PHP 7)

调用回调函数,并把一个数组参数作为回调函数的参数

说明

call_user_func_array(callable $callback,array $param_arr): mixed

把第一个参数作为回调函数($callback)调用,把参数数组作($param_arr)为回调函数的的参数传入。

参数

$callback

被调用的回调函数。

$param_arr

要被传入回调函数的数组,这个数组得是索引数组。

返回值

返回回调函数的结果。如果出错的话就返回FALSE

更新日志

版本说明
5.3.0对面向对象里面的关键字的解析有所增强。在此之前,使用两个冒号来连接一个类和里面的一个方法,把它作为参数来作为回调函数的话,将会发出一个E_STRICT的警告,因为这个传入的参数被视为静态方法。

范例

Example #1call_user_func_array()例子

以上例程的输出类似于:

foobar got one and two
foo::bar got three and four

Example #2call_user_func_array()使用命名空间的情况

以上例程的输出类似于:

Hello Hannes!
Hello Philip!

把完整的函数作为回调传入call_user_func_array()

以上例程会输出:

int(8)

传引用

以上例程会输出:

function mega $a=55
global $bar=55

注释

Note:

call_user_func_array() - php 选项信息函数

PHP 5.4之前,如果$param_arr里面的参数是引用传值,那么不管原函数默认的各个参数是不是引用传值,都会以引用方式传入到回调函数。虽然以引用传值这种方式来传递参数给回调函数,不会发出不支持的警告,但是不管怎么说,这样做还是不被支持的。并且在PHP 5.4里面被去掉了。而且,这也不适用于内部函数,for which the function signature is honored。如果回调函数默认设置需要接受的参数是引用传递的时候,按值传递,结果将会输出一个警告。call_user_func()将会返回FALSE(there is, however, an exception for passed values with reference count = 1, such as in literals, as these can be turned into references without ill effects — but also without writes to that value having any effect —; do not rely in this behavior, though, as the reference count is an implementation detail and the soundness of this behavior is questionable)。Note:

在函数中注册有多个回调内容时(如使用call_user_func()与call_user_func_array()),如在前一个回调中有未捕获的异常,其后的将不再被调用。

参见

  • call_user_func() 把第一个参数作为回调函数调用
  • callback类型的信息
  • ReflectionFunction::invokeArgs() Invokes function args
  • ReflectionMethod::invokeArgs() 带参数执行
As of PHP 5.6 you can utilize argument unpacking as an alternative to call_user_func_array, and is often 3 to 4 times faster.

Benchmarks from https://gist.github.com/nikic/6390366
cufa  with 0 args took 0.43453288078308
switch with 0 args took 0.24134302139282
unpack with 0 args took 0.12418699264526
cufa  with 5 args took 0.73408579826355
switch with 5 args took 0.49595499038696
unpack with 5 args took 0.18640494346619
cufa  with 100 args took 5.0327250957489
switch with 100 args took 5.291127204895
unpack with 100 args took 1.2362589836121
Just hope this note helps someone (I killed the whole day on issue).
If you use something like this in PHP 
For anyone looking for the means to test for the first parameter before passing to this function, look at the is_callable (http://php.net/manual/en/function.is-callable.php) variable handler. 
It appears that when PHP executes something like:
$a = array(1,2,3);
$b =& $a[1];
both $b and $a[1] are converted into references to a common value -- makes sense until you transfer that to a call_user_func:
call_user_func_array('foo', $a);
suddenly, inside foo, the second parameter is passed by reference!
And you can't call this wrong, only another subtly of references.
Note it appears that ksort($a) will remove the reference as well as put the elements in key order so you (probably) get what you expect. (see below on the use of a foreach ($a as &v).)
Just a heads up, the second parameter MUST be an array if it's specified, but that doesn't seem to be enforced until ~5.3.
I just pulled my hair out with an old installation of CakePHP because it was passing NULL instead of an empty array.
Please note, that when calling call_user_func_array() to redirect parameters between inherited classes, you should not use $this, because $this always refers to the class which has been instantiated. The following code even seems to crash PHP (PHP does not report error but the process simply terminates), because the the parameters are redirected only one level up (to class foo_bar2):

Instead, use the direct name of the class as string or, better, the magic constant __CLASS__ in call_user_func_array(), like:
  call_user_func_array(array(__CLASS__, 'parent::__construct'), $constructorArgs);
Then the parameters will be correctly redirected to the lowest base class.
Those having the passing by reference issue can use this simple hack.
I´m really not sure WHY this works, but it does, and it does not make use of EVAL or other questionable functions.

All it´s doing is copying the args ($args) into a new array ($Args) by reference, which i would think would be identical to the original array in every way (that matters).
Note the code here is an example of usage. The actual hack is denoted by comments.
If someone knows a better alternative, by all means, i would love to see it.
$param_arr may be empty, though it can't be null.

鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com

免责声明:我们致力于保护作者版权,注重分享,当前被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!邮箱:344225443@qq.com)

图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

内容声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。部分内容参考包括:(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供参考使用,不准确地方联系删除处理!本站为非盈利性质站点,本着为中国教育事业出一份力,发布内容不收取任何费用也不接任何广告!)