PHP函数处理 函数(1): call_user_func(_array)、func_get_arg(s)、func_num_args

2024-05-02 13:48

本文主要是介绍PHP函数处理 函数(1): call_user_func(_array)、func_get_arg(s)、func_num_args,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

函数简介

call_user_func_array

mixed call_user_func_array ( callable $callback , array $param_arr )
把第一个参数作为回调函数(callback)调用,把参数数组(param_arr)作为回调函数的的参数传入。param_arr 要被传入回调函数的数组,这个数组得是索引数组。参数可以引用传递。

call_user_func

mixed call_user_func ( callable $callback [, mixed $parameter [, mixed $… ]] )
第一个参数 callback 是被调用的回调函数,其余参数是回调函数的参数。
parameter 0个或以上的参数,被传入回调函数。传入call_user_func()的参数不能为引用传递。

func_get_args

array func_get_args ( void ) 获取函数参数列表的数组。
返回一个数组,其中每个元素都是目前用户自定义函数的参数列表的相应元素的副本。

func_num_args

int func_num_args ( void )
Gets the number of arguments passed to the function.

func_get_arg

mixed func_get_arg ( int $arg_num )
从用户自定义函数的参数列表中获取某个指定的参数。
arg_num 参数的偏移量。函数的参数是从0开始计数的。当 arg_num 比实际传入的参数的数目大或小于0的时候发出一个警告,返回 FALSE 。

应用

call_user_func_array

场景一:函数名是未知、函数的参数类型及个数也是未知的
场景二:用于函数回调,回调函数可能是一个普通函数(动态调用普通函数,类似可变函数),可能是类方法,也可能是静态方法。如果使用call_user_func_array,你就不用去判断方法的类型

可以调用静态方法

class mrClass {function test() {if (is_object($this)) {// do something for instance method 实例调用echo 'this is an instance call <br />' . "\n";} else {// do something different for procedural methodecho 'this is a procedure call <br />' . "\n";}}static function testStatic() {if (is_object($this)) {// do something for instance method 实例调用echo 'this is an instance call <br />' . "\n";} else {// do something different for procedural methodecho 'this is a procedure call <br />' . "\n";}}
}$inst = new mrClass();
$inst->test();//Strict standards: Non-static method mrClass::test() should not be called statically
mrClass::test();//静态调用,没有生成$this,输出$this为null,并报错。is_object(null)返回false//Strict standards: Non-static method mrClass::test() should not be called statically
mrClass::testStatic();//静态调用,没有生成$this,输出$this为null,并报错echo '<hr>';//Notice: Undefined variable: this, $this报的错,而不是调用报的错
call_user_func_array(array('mrClass','testStatic'),[]);

可以引用

function increment(&$var)
{$var++;
}$a = 0;
//call_user_func('increment', &$a);//Fatal error: Call-time pass-by-reference has been removed in ...
call_user_func('increment', $a);//Warning: Parameter 1 to increment() expected to be a reference, value given in ...echo $a."\n";call_user_func_array('increment', array(&$a)); // You can use this instead before PHP 5.3
echo $a."\n";//以上例程会输出:
//0
//1

func_num_args、func_get_arg

function foo()
{$numargs = func_num_args();echo "Number of arguments: $numargs<br />\n";if ($numargs >= 2) {echo "Second argument is: " . func_get_arg(1) . "<br />\n";//var_dump(func_get_arg(-1)); //Warning: func_get_arg(): The argument number should be >= 0 in 。。。//var_dump(func_get_arg(6)); //Warning: func_get_arg(): Argument 6 not passed to function in 。。。}$arg_list = func_get_args();for ($i = 0; $i < $numargs; $i++) {echo "Argument $i is: " . $arg_list[$i] . "<br />\n";}
}foo(1, 2, 3);/*
以上例程会输出:Number of arguments: 3<br />Second argument is: 2<br />Argument 0 is: 1<br />Argument 1 is: 2<br />Argument 2 is: 3<br />
*/

call_user_func与直接调用速度区别

在php中,使用“变量函数”(variiable function)会比call_user_func()慢,而call_user_func_array()比call_user_func()还要更慢。

相关的benchmark如下:


# Benchmark (2 million iterations)# Operation                    Seconds
# Literal function          1.218
# Variable function         1.305
# call_user_func()          2.734
# call_user_func_array()    3.386

可以看到,变量函数和普通函数调用(literal function)速度差别不大,和call_user_func相差有一倍以上,而call_user_func_array则要更慢。所以你给的代码才会尽量避免使用call_user_func_array而更倾向于使用变量函数。因为只有很少的函数会有5个以上的参数,所以上面代码里才把1到5个函数的调用用变量函数来写,而只留下小部分的函数用call_user_func_array调用,从而最大的加快程序执行速度。

其实,这些函数的效率差异不会有想象的那么大,上面的benchmark是迭代200万次的结果,如果你的程序只会调用’call_user_func_array’几千次或以下,这些差异将会非常小(大概是0.002秒左右)。

参考

php.net
php call_user_func_array函数有什么不好的地方吗?
php问题 call_user_func_array 这个函数什么时候用?最近再看tp框架 很多地方用到了这个函数
使用call_user_func_array()来回调执行函数与直接使用函数的区别是什么?
Benchmarking magic–PHP

这篇关于PHP函数处理 函数(1): call_user_func(_array)、func_get_arg(s)、func_num_args的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/954393

相关文章

Go语言使用Buffer实现高性能处理字节和字符

《Go语言使用Buffer实现高性能处理字节和字符》在Go中,bytes.Buffer是一个非常高效的类型,用于处理字节数据的读写操作,本文将详细介绍一下如何使用Buffer实现高性能处理字节和... 目录1. bytes.Buffer 的基本用法1.1. 创建和初始化 Buffer1.2. 使用 Writ

Python视频处理库VidGear使用小结

《Python视频处理库VidGear使用小结》VidGear是一个高性能的Python视频处理库,本文主要介绍了Python视频处理库VidGear使用小结,文中通过示例代码介绍的非常详细,对大家的... 目录一、VidGear的安装二、VidGear的主要功能三、VidGear的使用示例四、VidGea

Python结合requests和Cheerio处理网页内容的操作步骤

《Python结合requests和Cheerio处理网页内容的操作步骤》Python因其简洁明了的语法和强大的库支持,成为了编写爬虫程序的首选语言之一,requests库是Python中用于发送HT... 目录一、前言二、环境搭建三、requests库的基本使用四、Cheerio库的基本使用五、结合req

使用Python处理CSV和Excel文件的操作方法

《使用Python处理CSV和Excel文件的操作方法》在数据分析、自动化和日常开发中,CSV和Excel文件是非常常见的数据存储格式,ython提供了强大的工具来读取、编辑和保存这两种文件,满足从基... 目录1. CSV 文件概述和处理方法1.1 CSV 文件格式的基本介绍1.2 使用 python 内

Oracle的to_date()函数详解

《Oracle的to_date()函数详解》Oracle的to_date()函数用于日期格式转换,需要注意Oracle中不区分大小写的MM和mm格式代码,应使用mi代替分钟,此外,Oracle还支持毫... 目录oracle的to_date()函数一.在使用Oracle的to_date函数来做日期转换二.日

如何使用celery进行异步处理和定时任务(django)

《如何使用celery进行异步处理和定时任务(django)》文章介绍了Celery的基本概念、安装方法、如何使用Celery进行异步任务处理以及如何设置定时任务,通过Celery,可以在Web应用中... 目录一、celery的作用二、安装celery三、使用celery 异步执行任务四、使用celery

SpringBoot操作spark处理hdfs文件的操作方法

《SpringBoot操作spark处理hdfs文件的操作方法》本文介绍了如何使用SpringBoot操作Spark处理HDFS文件,包括导入依赖、配置Spark信息、编写Controller和Ser... 目录SpringBoot操作spark处理hdfs文件1、导入依赖2、配置spark信息3、cont

SpringBoot中Get请求和POST请求接收参数示例详解

《SpringBoot中Get请求和POST请求接收参数示例详解》文章详细介绍了SpringBoot中Get请求和POST请求的参数接收方式,包括方法形参接收参数、实体类接收参数、HttpServle... 目录1、Get请求1.1 方法形参接收参数 这种方式一般适用参数比较少的情况,并且前后端参数名称必须

PHP执行php.exe -v命令报错的解决方案

《PHP执行php.exe-v命令报错的解决方案》:本文主要介绍PHP执行php.exe-v命令报错的解决方案,文中通过图文讲解的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下... 目录执行phpandroid.exe -v命令报错解决方案执行php.exe -v命令报错-PHP War

MyBatis延迟加载的处理方案

《MyBatis延迟加载的处理方案》MyBatis支持延迟加载(LazyLoading),允许在需要数据时才从数据库加载,而不是在查询结果第一次返回时就立即加载所有数据,延迟加载的核心思想是,将关联对... 目录MyBATis如何处理延迟加载?延迟加载的原理1. 开启延迟加载2. 延迟加载的配置2.1 使用