php CALL_USER_FUNC与实例化的区别

使用call_user_func函数,通过传入字符串函数,可以调用自定义函数,并且支持引用。

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

调用第一个参数提供的自定义函数,后面的参数为自定义函数的参数,返回自定义函数的结果

function say($word)
{
    echo $word;
}
call_user_func('say', 'hello world'); //hello world

使用call_user_func可以执行一个类的某个方法,而且可以给方法传参数,它跟实例化一个类再调用方法有什么区别呢?看下面的例子。

class A
{
    public function __Construct($a,$b,$c)
    {
        echo 'Construct'.$a.$b.$c;
    }
 
    public function test($a,$b,$c)
    {
        echo ' test'.$a.$b.$c;
    }
}
 
$a = new A(1,2,3);
$a->test(1,2,3);
 
call_user_func(['A','test'],1,2,3);

类A有一个构造方法,如果用实例化的方式new A,会执行构造函数,而使用call_user_func的方式调用test方法,并没有出发构造函数,虽然都可以执行到方法,这就是两者的区别。

那么在有的情况下,并不能直接实例化一个类,希望通过其他方式去得到一个类,而且能够执行类的构造方法怎么办?

此时可以使用类的反射类和newInstanceArgs来创建一个新的类的实例,代码如下:

 

$reflection = new ReflectionClass('A');
$newclass = $reflection->newInstanceArgs([1,2,3]);
$newclass->test(1,2,3);

它的效果等同于:

$a = new A(1,2,3);
$a->test(1,2,3);

具体可以参见

首先定义一个类A,用ReflectionClass得到A的反射类对象,通过ReflectionClass对象可以得到类的各种属性,包括命名空间,父类,类名等,使用newInstanceArgs可以传入构造函数的参数创建一个新的类的实例。

class A
{
    public $name;
 
    public function __Construct($name,$des)
    {
        $this->name = $name.','.$des;
    }
    public function aa()
    {
        echo $this->name;
    }
}
 
$class = new ReflectionClass('A');
 
$aaa = $class->newInstanceArgs(['www.111cn.net','blog']);
 
$aaa->aa();

输出结果:www.111cn.net,blog

以上示例中的$aaa即是通过newInstanceArgs创建的一个新的A类的实例,因此它可以调用A类的方法aa(),值得注意的是newInstanceArgs创建新类必须传参,也就是要求这个类要有构造方法。

时间: 2024-10-01 23:46:59

php CALL_USER_FUNC与实例化的区别的相关文章

java类的问题-Java类的实例化,对象的声明,使用

问题描述 Java类的实例化,对象的声明,使用 有没有哪位大神帮忙解释一下图中的代码,本人是新手,希望各位前辈指教 解决方案 创建一个person类 类里面两个变量一个方法 方法体的内容是打印这个类里面变量的值 然后书上写错了 应该是person 不是person2 解决方案二: 书上说的很清楚了. 比如 int i = 1; 这个你懂么? i是一个int型的变量,初始化值指向一个整数1. 那么 helloworld c = new helloworld(); c是一个helloworld型的变

java中“==”为什么会出现这种现象

问题描述 classTest{publicstaticvoidmain(String[]args){Stringa=newString("taoyu");Stringb=newString("taoyu");System.out.println(a==b);}}结果为:falseclassTest{publicstaticvoidmain(String[]args){Stringa=newString("taoyu");Stringb=newSt

(一〇六)函数模板

函数模板的意义在于,可以在不同的参数下,起到同样的作用. 按照教程所说,它们使用泛型来定义函数,其中泛型可用具体的类型(如int.double)替换.通过将类型作为参数传递给模板,可使编译器生成该类型的函数.   由于模板允许以泛型(而不是具体的类型)的方式编写程序,因此在有时也会被称为是通用编程.   由于类型是用参数表示的,因此模板特性有时也被称为参数化类型.   格式: template <typename xx> void 函数名(xx &a, xx &b) { xx

《UVM实战》——2.2节只有driver的验证平台

2.2 只有driver的验证平台 driver是验证平台最基本的组件,是整个验证平台数据流的源泉.本节以一个简单的DUT为例,说明一个只有driver的UVM验证平台是如何搭建的. 2.2.1 最简单的验证平台 在本章中,假设有如下的DUT定义: 代码清单 2-1 1 module dut(clk, 2 rst_n, 3 rxd, 4 rx_dv, 5 txd, 6 tx_en); 7 input clk; 8 input rst_n; 9 input[7:0] rxd; 10 input r

VC++角色游戏中的人物初始化模块代码实例_C 语言

本文以一个实例讲述VC++游戏中的人物角色动画初始化实现代码,本代码只是实现人物角色动画的初始化,不包括其它功能,并不是完整的一个游戏应用,现在将这个角色初始化代码与大家分享.希望能够对大家学习VC++有所帮助. #include "StdAfx.h" #include "Character.h" CCharacter::CCharacter(void) { } CCharacter::~CCharacter(void) { } //初始化人物 bool CChar

C++ 初始化列表详解及实例代码_C 语言

C++ 初始化列表 何谓初始化列表 与其他函数不同,构造函数除了有名字,参数列表和函数体之外,还可以有初始化列表,初始化列表以冒号开头,后跟一系列以逗号分隔的初始化字段.在C++中,struct和class的唯一区别是默认的访问性不同,而这里我们不考虑访问性的问题,所以下面的代码都以struct来演示. struct foo { string name ; int id ; foo(string s, int i):name(s), id(i){} ; // 初始化列表 }; 构造函数的两个执行

javascript中使用new与不使用实例化对象的区别

  这篇文章主要介绍了javascript中使用new与不使用实例化对象的区别的相关资料,需要的朋友可以参考下 我们先来看个实例 ? 1 2 3 4 5 function Me(name,age,job){ this.name = name; this.age = age; this.job = job; } 请问这以下两种实例化对象方式有什么区别呢? ? 1 2 var mefun1 = new Me('fei','20','it'); var mefun2 = Me('fei','20','

实例化的对象和引用用变量在用法上有什么区别? 可以给出例子吗?

问题描述 实例化的对象和引用用变量在用法上有什么区别? 可以给出例子吗? 实例化的对象和引用用变量在用法上有什么区别? 可以给出例子吗? 解决方案 因为实例化过程其实是在内存.堆栈开辟空间的过程,实例化以后拥有内存空间才可以进行一系列操作(操作系统方面的知识可解惑): 初学可以认为两者用法一样,深入那么一点就是内存空间不一样,再深入一点--(不做性能优化木有了解也不碍事) 解决方案二: 个人认为两者其实差别还是很大的,简单来说,实例化的对象和未实例化的对象区别在于有没有赋值,而变量形象的讲,就是

ThinkPHP中实例化对象M()和D()的区别,select和find的区别

原文:ThinkPHP中实例化对象M()和D()的区别,select和find的区别 1.ThinkPHP中实例化对象M()和D()的区别 在实例化的过程中,经常使用D方法和M方法,这两个方法的区别在于M方法实例化模型无需用户为每个数据表定义模型类,如果D方法没有找到定义的模型类,则会自动调用M方法.通俗一点说:M实例化参数是数据库的表名.D实例化的是你自己在Model文件夹下面建立的模型文件 例如:$user = new UserModel(); 等价于$user = D('user'); 如