一、什么是魔术方法?

魔术方法是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. OpenFlow技术白皮书-V1.0

    1.  概述 OpenFlow是由斯坦福大学的Nick McKeown教授在2008年4月ACM Communications Review上发表的一篇论文OpenFlow: enabling inn ...

  2. windows cmd 命令行 —— 进程与服务

    1. 进程查看与操作 tasklist tskill pid 2. 服务查看与操作 net start net stop

  3. UNIX 环境高级编程 文件和目录

    函数stat , fstat , fstatat , lstat stat函数返回与此文件有关的信息结构. fstat函数使用已打开的文件描述符(而stat则使用文件名) fstatat函数 为一个相 ...

  4. 【剑指offer】不使用新变量,交换两个变量的值,C++实现

    # 题目 不使用新变量,交换两个变量的值. # 思路 方法一:使用加减法操作,交换两个变量的值. A = A+B B = A-B A = A-B 方法二:使用异或运算,交换两个变量的值 A = A^B ...

  5. CXF生成本地ws调用代码测试webservice

    package com.free.webservice.client; import java.util.List; import cn.com.webxml.*; public class Weat ...

  6. Java 输出文件通过 BufferedWriter.newline() 方法换行

    最近项目中需要导出文件,其实导出文件是一个挺简单的事情.但是却遇到了很奇怪的问题. 首先导出到文件需要用到 BufferedWriter.而换行则是通过 bw.newline() 方法,问题将出在 n ...

  7. DispatcherServlet的初始化(二)

    DispatcherServlet的初始化在springmvc的启动中有讲过,这一篇在上一篇的基础上接着讲.DispatcherServlet作为springmvc的前端控制器,还需要初始化其他的模块 ...

  8. [MEF]第03篇 MEF延迟加载导出部件及元数据

    一.演示概述此演示介绍了MEF的延迟加载及元数据相关的内容.在实际的设计开发中,存在着某些对象是不需要在系统运行或者附属对象初始化的时候进行实例化的,只需要在使用到它的时候才会进行实例化,这种方式就可 ...

  9. cocos2d

    http://www.jetbrains.com/webstorm/download/index.html 运行又有下面错误 Fatal signal 11 (SIGSEGV) at 0x000000 ...

  10. SmtpClient发送邮件

    使用第三方SMTP服务器来发送邮件.如网易: SmtpClient sc = new SmtpClient("smtp.126.com"); sc.Credentials = ne ...