PHP call_user_func和call_user_func_array函数的简单理解与应用分析


Posted in PHP onNovember 25, 2019

本文实例讲述了PHP call_user_func和call_user_func_array函数的简单理解与应用。分享给大家供大家参考,具体如下:

call_user_func():调用一个回调函数处理字符串,
可以用匿名函数,可以用有名函数,可以传递类的方法,
用有名函数时,只需传函数的名称
用类的方法时,要传类的名称和方法名
传递的第一个参数必须为函数名,或者匿名函数,或者方法
其他参数,可传一个参数,或者多个参数,这些参数会自动传递到回调函数中
而回调函数,可以通过传参,获取这些参数
返回回调函数处理后的结果

①传递函数名,通过回调函数的形参获取call_user_func传参数的情况

<?php
//先引用后增加
function _call($call){
  //通过传参获取call_user_func传过来的参数
  echo $call++,'<br/>';
  echo $call++,"<br/>";
}
//上面回调函数没有返回值,所以,这里就没有返回值,_call为上面的函数的名称
$re = call_user_func('_call',1);
//实验结果为 null,符合上面的结论
var_dump($re);

②调用匿名函数传参的情况

<?php
//先增加后引用
call_user_func(function($call){
  echo ++$call,'<br/>';
  echo ++$call,'<br/>';
},1);//传给匿名函数的参数为···1···,执行的结果为2,3

③回调函数是匿名函数,并且匿名函数不设参数,通过其他方式获取参数的情况

<?php
$arg1 = 'first';
$arg2 = 'two';
$return = call_user_func(function(){
  $arg = func_get_arg(0); //func_get_arg函数作用:获取函数的第几个参数,必须要有参数,参数必须为函数参数的偏移量,0代表第一个参数
  $args = func_get_args();//func_get_args的作用:获取函数所有的参数
  if(func_num_args() == 1){//func_num_args函数的作用:获取函数参数的个数,注意,假如函数没有传参,该函数返回0
    return $args[0];
  }else{
    //用|把函数的参数组织成字符串
    return implode('|',$args);
  }
},$arg1,$arg2);
var_dump($return);

④调用···没有命名空间···的······类方法······的情况

<?php
class Func{
  //静态方法
  static public function _func(){
    $str = 'THE CLASS NAME IS '.__CLASS__.' AND CLASS STATIC METHOD IS '.__METHOD__;
    if(func_num_args()){
      //获取函数参数,获取参数也可以通过给方法设置形参来获取,这里只是没给方法设置形参获取参数的情况
      $arg = func_get_arg(0);
      return $str.' and argument is '.$arg;
    }else{
      return $str;
    }
  }
  //普通方法
  public function __func($num){
    return $num ? $num+1:$num;
  }
}
//传递类的静态方法,有两种方式
//(1)种,传递····类名::方法名····
var_dump(call_user_func("Func::_func",'hell world'));//这里传递参数
//(2)种,传递类名和方法名的数组
var_dump(call_user_func(array('Func','_func')));//这里没有传参数
$num = 4;
$o = new Func;
//传递类普通方法必须用···数组···传递···该类的对象··和···方法名···
$return = call_user_func(array($o,'__func'),$num);
var_dump($return);

⑤调用·····有命名空间的·······类方法·········的情况

<?php
//定义类的命名空间
namespace Home;
class Space{
  //静态方法
  static public function _call($num){
    return $num +=10;
  }
  //普通方法
  public function _func(){
    return func_get_args();//返回函数的参数
  }
}
//针对静态方法,有两种调用方式
//1.可以用array(__NAMESPACE__.'\类名','方法名')传递类方法,也就是:array('命名空间\类名','方法名')
$return = call_user_func(array(__NAMESPACE__.'\Space','_call'),10);
//2.可以用····  __NAMESPACE__.'\类名::方法名'  ···传递类方法,也就是:'命名空间\类名::方法名'
$return1 = call_user_func('Home\Space::_call',100);
var_dump($return);
var_dump($return1);
//针对普通方法,不用传入命名空间即可调用,如下
$o = new Space;
$return = call_user_func(array($o,'_func'),1,2,3,4,5);
var_dump($return);

call_user_func函数是php引用匿名函数的一种方式,php不像js那样,可以把匿名函数赋值给变量并引用,但可以通过call_user_func函数来调用匿名函数,这也能做到局部变量不被全局污染,call_user_func调用的回调函数不仅仅是我们自定义的函数,还可以是php处理字符串的系统函数,如rtrim、explode的,在调用这些系统函数时,需要注意的是,call_user_func传递的参数必须符合系统函数的传参顺序,你自己可以试着调用一下,举个例子:调用rtrim和explode函数。下面的例子本人试过,是可行的

<?php
$return = call_user_func('rtrim','sso;osoo;',';');
$return2 = call_user_func('explode',';','sso;osoo;');
var_dump($return);
var_dump($return2);

与call_user_func函数类似的还有一个call_user_func_array函数,这个函数的调用和作用和call_user_func函数基本一样,所不同的是,call_user_func_array函数只能传递两个参数,第一个是回调函数名,或者匿名函数,或者类方法,第二个参数则是数组,从这里也可以看出,其实call_user_func_array函数与call_user_func不同的是,call_user_func_array是利用回调函数处理数组,而call_user_func则是利用回调函数处理字符串,他们两个的根本差别就在这里了。你自己可以尝试的调用call_user_func_array()函数,因为它们的引用基本一样,所以关于call_user_func_array就不再多写了。

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
php中取得URL的根域名的代码
Mar 23 PHP
PHP ? EasyUI DataGrid 资料存的方式介绍
Nov 07 PHP
php中用加号与用array_merge合并数组的区别深入分析
Jun 03 PHP
PHP中使用smarty生成静态文件的例子
Apr 24 PHP
10个简化PHP开发的工具
Dec 25 PHP
php返回当前日期或者指定日期是周几
May 21 PHP
php遍历解析xml字符串的方法
May 05 PHP
PhpStorm terminal无法输入命令的解决方法
Oct 09 PHP
php 判断过去离现在几年的函数(实例代码)
Nov 15 PHP
strpos() 函数判断字符串中是否包含某字符串的方法
Jan 16 PHP
PHP PDOStatement::bindColumn讲解
Jan 30 PHP
php写入txt乱码的解决方法
Sep 17 PHP
使用Git实现Laravel项目的自动化部署
Nov 24 #PHP
PhpStorm 如何优雅的调试Hyperf的方法步骤
Nov 24 #PHP
laravel框架中视图的基本使用方法分析
Nov 23 #PHP
laravel框架中表单请求类型和CSRF防护实例分析
Nov 23 #PHP
laravel框架中控制器的创建和使用方法分析
Nov 23 #PHP
laravel框架模型中非静态方法也能静态调用的原理分析
Nov 23 #PHP
laravel框架中路由设置,路由参数和路由命名实例分析
Nov 23 #PHP
You might like
php 随机数的产生、页面跳转、件读写、文件重命名、switch语句
2009/08/07 PHP
彻底杜绝PHP的session cookie错误
2009/08/09 PHP
PHP 5.3.1 安装包 VC9 VC6不同版本的区别是什么
2010/07/04 PHP
对象失去焦点时自己动提交数据的实现代码
2012/11/06 PHP
基于Zend的Captcha机制的应用
2013/05/02 PHP
Ubuntu上安装yaf扩展的方法
2018/01/29 PHP
php设计模式之状态模式实例分析【星际争霸游戏案例】
2020/03/26 PHP
phpstorm最新激活码分享亲测phpstorm2020.2.3版可用
2020/11/22 PHP
基于jQuery捕获超链接事件进行局部刷新代码
2012/05/10 Javascript
node.js中的fs.readFileSync方法使用说明
2014/12/15 Javascript
Javascript基于对象三大特性(封装性、继承性、多态性)
2016/01/04 Javascript
Vuex2.0+Vue2.0构建备忘录应用实践
2016/11/30 Javascript
jQuery操作之效果详解
2017/05/19 jQuery
jquery请求servlet实现ajax异步请求的示例
2017/06/03 jQuery
基于BootStrap的文本编辑器组件Summernote
2017/10/27 Javascript
轻量级JS Cookie插件js-cookie的使用方法
2018/03/22 Javascript
js实现敏感词过滤算法及实现逻辑
2018/07/24 Javascript
Vue.js 十五分钟入门图文教程
2018/09/12 Javascript
微信小程序外卖选购页实现切换分类与数量加减功能案例
2019/01/15 Javascript
ES10 特性的完整指南小结
2019/03/04 Javascript
优雅的将ElementUI表格变身成树形表格的方法步骤
2019/04/11 Javascript
node.js 使用 net 模块模拟 websocket 握手进行数据传递操作示例
2020/02/11 Javascript
ES6使用 Array.includes 处理多重条件用法实例分析
2020/03/02 Javascript
通过JS判断网页是否为手机打开
2020/10/28 Javascript
WebStorm中如何将自己的代码上传到github示例详解
2020/10/28 Javascript
Vue获取微博授权URL代码实例
2020/11/04 Javascript
[22:20]初生之犊-TI4第5名LGD战队纪录片
2014/08/13 DOTA
[01:45]典藏宝瓶2+祈求者身心——这就是DOTA2TI9总奖金突破3000万美元的秘密
2019/07/21 DOTA
Python书单 不将就
2017/07/11 Python
python写一个md5解密器示例
2018/02/23 Python
Python实现AES加密,解密的两种方法
2020/10/03 Python
BeautifulSoup中find和find_all的使用详解
2020/12/07 Python
意大利会呼吸的鞋:Geox健乐士
2017/02/12 全球购物
学习十八大坚定理想信念心得体会
2014/03/11 职场文书
《窗前的气球》教学反思
2014/04/07 职场文书
解决Swagger2返回map复杂结构不能解析的问题
2021/07/02 Java/Android