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

call_user_func() - php 选项信息函数

百变鹏仔12个月前 (11-21)阅读数 17#技术干货
文章标签回调

call_user_func()

(PHP 4, PHP 5, PHP 7)

把第一个参数作为回调函数调用

说明

call_user_func(callable $callback[,mixed $parameter[,mixed$...]]): mixed

第一个参数$callback是被调用的回调函数,其余参数是回调函数的参数。

参数

$callback

将被调用的回调函数(callable)。

$parameter

0个或以上的参数,被传入回调函数。

Note:

请注意,传入call_user_func()的参数不能为引用传递。

call_user_func() - php 选项信息函数

Example #1call_user_func()的参考例子

以上例程会输出:

0 1

返回值

返回回调函数的返回值。

更新日志

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

范例

Example #2call_user_func()的例子

以上例程会输出:

You wanted a mushroom haircut, no problem
You wanted a shave haircut, no problem

Example #3call_user_func()命名空间的使用

以上例程会输出:

Hello world!
Hello world!

call_user_func()来调用一个类里面的方法

以上例程会输出:

Hello!
Hello!
Hello!

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

以上例程会输出:

[test]

注释

Note:

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

参见

  • call_user_func_array() 调用回调函数,并把一个数组参数作为回调函数的参数
  • is_callable() 检测参数是否为合法的可调用结构
  • callback类型的信息
  • ReflectionFunction::invoke() Invokes function
  • ReflectionMethod::invoke() Invoke
I benchmarked the comparison in speed between variable functions, call_user_func, and eval. My results are below:
Variable functions took 0.125958204269 seconds.
call_user_func took 0.485446929932 seconds.
eval took 2.78526711464 seconds.
This was run on a Compaq Proliant server, 180MHz Pentium Pro 256MB RAM. Code is as follows: 
if you simply want to dynamically call a method on an object it is not necessary to use call_user_function but instead you can do the following:

I've used the above so I know it works.
Regards,
-- Greg
@insta at citiesunlimited dot com & @Maresa
call_user_func() alleged slowness is quite over estimated when it comes to real use cases. we are talking about loosing fraction of a second every million calls, which by the way would take less than half a sec to execute in the worst case.
I don't know of many processes that would actually suffer from this kind of overhead.
Iterations: 100 000
Averaged over: 10
PHP 5.6.30 (cli) (built: Jan 18 2017 19:47:28)
Overall Average
+------------------------+----------+-----------+--------+
| Invocation       | Time (s) | Delta (s) | %   |
+------------------------+----------+-----------+--------+
| directFunction     | 0.0089  | -0.0211  | -70.19 |
| directStatic      | 0.0098  | -0.0202  | -67.39 |
| directLambda      | 0.0109  | -0.0191  | -63.52 |
| directInstance     | 0.0116  | -0.0184  | -61.31 |
| directClosure     | 0.0150  | -0.0150  | -50.15 |
| Invoke         | 0.0282  | -0.0018  | -6.13 |
| call_user_func     | 0.0300  |      |    |
| ClosureFactory     | 0.0316  | +0.0016  | +5.20 |
| assignedClosureFactory | 0.0328  | +0.0028  | +9.28 |
| call_user_func_array  | 0.0399  | +0.0099  | +33.02 |
| InvokeCallUserFunc   | 0.0418  | +0.0118  | +39.17 |
| directImplementation  | 0.0475  | +0.0175  | +58.28 |
+------------------------+----------+-----------+--------+
Iterations: 100 000
Averaged over: 10
PHP 7.1.2 (cli) (built: Feb 14 2017 21:24:45) 
Overall Average
+------------------------+----------+-----------+--------+
| Invocation       | Time (s) | Delta (s) | %   |
+------------------------+----------+-----------+--------+
| directFunction     | 0.0043  | -0.0096  | -68.92 |
| directStatic      | 0.0050  | -0.0089  | -64.04 |
| directInstance     | 0.0058  | -0.0081  | -58.22 |
| directLambda      | 0.0063  | -0.0075  | -54.44 |
| directClosure     | 0.0081  | -0.0058  | -41.57 |
| call_user_func     | 0.0139  |      |    |
| call_user_func_array  | 0.0147  | +0.0008  | +5.84 |
| Invoke         | 0.0187  | +0.0048  | +34.61 |
| ClosureFactory     | 0.0207  | +0.0069  | +49.43 |
| assignedClosureFactory | 0.0219  | +0.0080  | +57.75 |
| directImplementation  | 0.0232  | +0.0094  | +67.53 |
| InvokeCallUserFunc   | 0.0264  | +0.0126  | +90.67 |
+------------------------+----------+-----------+--------+
If you want more details : https://github.com/fab2s/call_user_func
A good use for call_user_func(); is for recursive functions.
If you're distributing code, you will often come across users who will rename functions and break the code..
Use this: call_user_func(__FUNCTION__, ... ); inside a function to call itself with whatever parameters you want.

The crash occurs when call_user_func() is called as it does not provide increment() with a reference.
Also note that :

will also throw an exception : 
An entirely OO solution to add dynamicly methods to classes, I used in a project:

I simplified the class somewhat for clearity.
With this class, you can dynamicly add and remove classes by calling register or unregister. Register will store the object in an associative array by calling toString (as defined by ProductPlugin) and saving the method under the returned string in the array. (In this case the name of the method the class adds.)
When a method is called, which isn't standard in the object, _call will lookup the called method in the array. If found, __call run the method of the plugin with the provided arguments. I restricted the user provided argument to 1, because I want to force the user to use associative arrays.
Because I chose an array to store my classes, removing a function is quite simple. However the unregister function isn't optimal, I better pass a string instead of a plugin object. I didn't test it yet on performance.
The ProductPlugin class:

And at last some demonstration code: 
You don't need to use this function to call a variable class function. Instead you can do the following:
$this->{$fnname}();
The example works in PHP 5 from within the class. It is the {} that do the trick.
Regards,
Julian.
I tested the same code that insta at citiesunlimited dot com pasted on the following machines:
www1 machine:
OS: FreeBSD 5.2.1-RELEASE
CPU: 2 x Intel(R) Xeon(TM) CPU 2.66GHz (2657.82-MHz 686-class CPU) with Hyperthreading
MEM: 1073217536 (1023 MB)
PHP 5.1.2 (cli)
PHP 4.4.1 (Web)
www2 machine:
OS: Linux version 2.6.14-gentoo-r5 Gentoo 3.4.3-r1, ssp-3.4.3-0, pie-8.7.7)
CPU: 2 x Dual Core AMD Opteron(tm) Processor 265 stepping 02 1808.357 MHz
MEM: 2060388k total
PHP 5.1.2 (cli)
PHP Version 4.4.0-pl1-gentoo (web)
dev machine:
OS: Linux version 2.6.15-gentoo-r1 Gentoo 3.3.5.20050130-r1, ssp-3.3.5.20050130-1, pie-8.7.7.1
CPU: Intel(R) Pentium(R) 4 CPU 2.00GHz stepping 04
MEM: 516384k total,
PHP 4.4.0-pl1-gentoo (cli)
PHP Version 4.4.0-pl1-gentoo (web)
The result are as follows:
www1 - CLI
Variable functions took 0.012186050415 seconds.
call_user_func took 0.0300550460815 seconds.
eval took 0.17235994339 seconds.
www1 - Web
Variable functions took 0.017616 seconds. 
call_user_func took 0.034926 seconds. 
eval took 0.149618 seconds
www2 - CLI
Variable functions took 0.0065491199493408 seconds.
call_user_func took 0.019452095031738 seconds.
eval took 0.10734891891479 seconds.
www2 - Web
Variable functions took 0.01565 seconds. 
call_user_func took 0.02613 seconds. 
eval took 0.132258 seconds.
dev - CLI
Variable functions took 0.025176 seconds.
call_user_func took 0.047402 seconds.
eval took 0.168196 seconds.
dev - Web
Variable functions took 0.025465 seconds. 
call_user_func took 0.049713 seconds. 
eval took 0.20154 seconds.
On www1 - CLI, eval is about 14 times slower than calling function by using variable.
On www1 - Web, eval is about 8.5 times slower (hmm interesting. Perhaps PHP4 is faster calculating eval than PHP5)
On www2 - CLI, eval is about 16 times slower than calling function by using variable.
On www2 - Web, eval is about 8.5 times slower (about same result as www1)
On dev - CLI, eval is about 6.6 times slower than calling function by using variable.
On dev - Web, eval is about 8 times slower (about same result as www1)
On the dev machine, CLI and web version of PHP is the same. and their speed difference between calling function using variable or eval does not differ that much compare to PHP5 VS PHP5
call_user_func may also be used to call a closure or anonymous function that has been passed into a user-defined function.

Returns:
Time: 0.001652
Time: 0.001458
>phil at gettcomm dot com
>22-May-2002 04:51
>if you need to get a reference back from a method, you can work around 
>call_user_func()'s shortcomings like this:
>
Naaa! Having back a reference is a real problem, but it can be solved by mean of eval(), instead of using call_user_func: 
I made a wrapper for call_user_func_array which is really simple and convenient. It takes advantage of the __invoke() magic method :

Example : 
Actually, as PHP 7.0, when you want to call a static method, you must call:

This will output:
Hello World!
Updating "insta at citiesunlimited dot com"'s benchmarking for PHP 7.1.17 we have an INVERSION of results between using variables and call_user_func():
// RESULTS 
Variable functions took 0.0020599365234375 seconds.
call_user_func took 0.00094509124755859 seconds.
eval took 0.024421215057373 seconds.
So, call_user_func() is now actually the way to go in PHP 7.1+. 
I was trying to use this function to call a method of an already-instantiated object. I needed to do this with the object itself, not simply call the class' method.
To accomplish this, I really avoided this particular function altogether like this:

I hope someone else finds this useful. Note that doing this allows you to pass params to the function more-or-less in the same way you would to any other class method.
Note that the parser can interpret variables in function syntax, which means you can pass all variables normally (eg: reference).

---
Hello World
1337

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

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

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

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