一、什么是魔术方法?

魔术方法是php中对一类方法的统称,这些方法可以在任何类中被实现。他们通常可以完成一些特殊的无法纯粹依靠自己编程实现的功能。他们通常以双下划线"__"作为名称开头。也因此,你要注意自定义的方法应该避免使用双下划线"__"开头。

二、什么是__call方法?

它是一种魔术变量,因此它可以在任何类中被实现,如果它被实现了,将由后台php解释器在运行过程中调用。

三、什么情况下会调用__call方法及其功能?

当你调用的方法不存在的时候,会解释器会调用__call方法,如下:

1.当成员方法存在的时候

<?php

/**
* Created by PhpStorm.
* User: funco
* Date: 17-6-11
* Time: 下午1:01
*/
class Test
{
public function showInfo() {
echo "run show Info";
} public function __call($name, $args) {
echo "run __call";
}
} $test = new Test();
$test->showInfo();

运行结果如下:

run show Info

2.当成员方法不存在的时候

<?php

/**
* Created by PhpStorm.
* User: funco
* Date: 17-6-11
* Time: 下午1:01
*/
class Test
{
public function showInfo() {
echo "run show Info";
} public function __call($name, $args) {
echo "run __call";
}
} $test = new Test();
$test->show();

运行结果如下:

run __call

也就是说实例化一个对象后,当调用这个对象的成员方法存在时,则直接调用其成员方法,但是当成员方法不存在时,将转而去调用__call方法。

同时__call必须有两个参数,这个参数名可以随意取,但是为了方便我们通常取为$name和$args

当成员方法不存在时,__call将被调用,同时,这个不存在的方法名称会作为字符串传递给第一个参数(这里第一个参数是$name),将调用时传递的参数作为列表传递给第二个参数(这里第二个参数是$args)。

可以参考一下下方样例:

<?php

/**
* Created by PhpStorm.
* User: funco
* Date: 17-6-11
* Time: 下午1:01
*/
class Test
{
public function showInfo() {
echo "run show Info";
} public function __call($name, $args) {
echo "\$name is \"{$name}\"\n";
print_r($args);// 数组无法直接使用echo输出 需要使用print_r输出
echo "\$args[0] is \"{$args[0]}\"";
}
} $test = new Test();
$test->show("string1","string2");

运行结果:

$name is "show"
Array
(
[0] => string1
[1] => string2
)
$args[0] is "string1"

简单的说,__call的功能就是这样,但是它具体有什么用呢?最直接的用法就是模拟面向对象的函数重载,php类是不支持像java的多态那样用不同的参数类型、参数数量来表达相同名称的不同函数的,只要名称同名,那么运行的时候就会报错,那么为了实现函数重载(多态),我们就可以利用__call方法实现。具体可以参考我的下一篇博文http://blog.csdn.net/qq_23937195/article/details/73027244

四、使用注意事项

__call在被实现时,必须有两个参数,否则运行后可能会报错,错误格式类似下方:

PHP Fatal error:  Method Test::__call() must take exactly 2 arguments

只有调用的方法不存在时,call方法才会被调用,如果调用的成员方法存在,__call将不会被调用。

只有__call方法被正确定义,当调用的方法不存在时才会调用__call方法,如果__call方法未被定义,你只会在控制台收到如下字符串打头的错误信息

PHP Fatal error:  Uncaught Error: Call to undefined method
阅读更多

魔术方法以及__call的调用的更多相关文章

  1. PHP面向对象魔术方法之__call函数

    l 基本介绍: (1) 当我们调了一个不可以访问的成员方法时,__call魔术方法就会被调用. (2) 不可以访问的成员方法的是指(1. 该成员方法不存在, 2. 成员方法是protected或者 p ...

  2. PHP常用魔术方法(__call魔术方法:)

    魔术方法  __call <?php //文件名:index.php define('a',__DIR__); include '/IMooc/Loader.php'; spl_autoload ...

  3. 魔术方法之__call与__callStatic方法

    <?php class human{ private function t(){ } /** * 魔术方法__call * * @param string $method 获得方法名 * @pa ...

  4. PHP魔术方法之__call与__callStatic方法

    <?php class human{ private function t(){ } //魔术方法__call /* $method 获得方法名 $arg 获得方法的参数集合 */ public ...

  5. 魔术方法之__call、__callStatic

    1.__call() 作用,当调用不存在的方法时,会调用该方法.实际应用,当程序调用不存在的方法时,意外导致程序终止. .或者当你调用了受保护的或者是私人的方法时,也会自动调用__call方法 结果: ...

  6. php类知识---魔术方法__toString,__call,__debugInfo

    <?php class mycoach{ public function __construct($name,$age) { $this->name = $name; $this-> ...

  7. PHP中的常用魔术方法

    魔术方法: 是指某些情况下,会自动调用的方法,称为魔术方法 php面向对象中,提供了这几个魔术方法,他们的特点都是 以双下划线__开头的 __construct()  构造方法 __destruct( ...

  8. php中常用魔术方法的举例

    魔术方法是php面向对象特有的功能,并且有时候能实现意想不到的效果,包括前面提到的构造函数.析构函数.还有__clone函数,另外再简单的介绍几个: 1.__toSring和__invoke clas ...

  9. php魔术方法的使用

    本文测试环境为 php5.5.12 一.__get .__set 将对象的属性进行接管. 一般来说,总是把类的属性定义为private,但是对属性的读取和赋值操作非常频繁,在php5+,预定义__se ...

随机推荐

  1. 【Python】Python点滴(一)——pip工具使用

    首先我们来看一条命令:pip install uwsgi 这条命令按照操作名称,可以分为三个部分:pip.install和uwsgi.接下来,按照这样三个部分进行分析.   pip pip类似于Rea ...

  2. Android上玩玩Hook:Cydia Substrate实战

    作者简介:周圣韬,百度高级Android开发工程师,博客地址:http://blog.csdn.net/yzzst 了解Hook 还没有接触过Hook技术读者一定会对Hook一词感觉到特别的陌生,Ho ...

  3. CF 148D D. Bag of mice (概率DP||数学期望)

    The dragon and the princess are arguing about what to do on the New Year's Eve. The dragon suggests ...

  4. eclipse添加propedit插件

    1.propedit插件 这个插件基本上可以支持各种语言的转换. 2.方法如下: “help”--“Install new software”--“add” name:propedit Locatio ...

  5. Hadoop1.x安装配置文件及参数说明

    一.常用文件及参数说明Core-site.xml       配置Common组件的属性 hdfs-site.xml         配置hdfs参数,比如备份数目,镜像存放路径 Mapred-sit ...

  6. LOJ#3054. 「HNOI 2019」鱼

    LOJ#3054. 「HNOI 2019」鱼 https://loj.ac/problem/3054 题意 平面上有n个点,问能组成几个六个点的鱼.(n<=1000) 分析 鱼题,劲啊. 容易想 ...

  7. 一款直接时空处理分析的开源数据库---geomesa

    一款直接时空处理分析的开源数据库---geomesa,可用于交通轨迹数据存储分析等相关领域, 在分布式列数据库的基础上进行扩展,目前支持Accumulo, HBase, Cassandra, and ...

  8. cockpit 使用(集成docker && k8s 管理)

    1. yum 安装 sudo yum install cockpit 2. 允许启动 sudo systemctl enable --now cockpit.socket 3. 可选的插件 cockp ...

  9. iptables规则绑定在port而不是拦截在协议栈

    版权声明:本文为博主原创,无版权.未经博主同意能够任意转载,无需注明出处,任意改动或保持可作为原创! https://blog.csdn.net/dog250/article/details/2417 ...

  10. bean作用域

    https://blog.csdn.net/u011468990/article/details/49995865 其中比较常用的是singleton和prototype两种作用域.对于singlet ...