PHP类中的魔术方法(Magic Method)简明总结


Posted in PHP onJuly 08, 2014

1. __construct()和__destruct()

在实例被 创建/销毁 的时候被调用,都可以传递0个或多个参数。

class A
 {
  function A()
  {
   echo "build A";
  }

  function __destruct()
  {
   echo "destroy A";
  }
 }

 $obj = new A();
 //unset($obj);

Note:The destructor method will be called as soon as there are no other references to a particular object, or in any order during the shutdown sequence.

关于构造函数,PHP5.3.3开始,一个定义在某个特定的命名空间里的class中以类名命名的方法将不再被认为是构造函数。在无命名空间的类中与原来一样依旧是构造函数。如:

namespace Foo;
class Bar {
  public function Bar() {
    // treated as constructor in PHP 5.3.0-5.3.2
    // treated as regular method as of PHP 5.3.3
  }
}

如果没有namespace Foo; 那么Bar()还将被当作构造函数。另外,如果存在下面的情况:

function __construct()
  {
   echo "construct A";
  }

  function A()
  {
   echo "build A";
  }

  function __destruct()
  {
   echo "destroy A";
  }
 }

即既包含__construct()又包含与类名同名的函数,那么将只调用__construct()。

2. __call()和__callStatic()

当尝试调用一个不存在的方法时调用该方法。两个参数,一个是方法名,一个是被调用方法的参数数组。

class MethodTest
{
  public function __call($name, $arguments)
  {
    // Note: value of $name is case sensitive.
    echo "Calling object method '$name' "
       . implode(' ', $arguments). "<br>";
  }

  public static function __callStatic($name, $arguments)
  {
    // Note: value of $name is case sensitive.
    echo "Calling static method '$name' "
       . implode(' ', $arguments). "<br>";
  }
}

$obj = new MethodTest;
$obj->runTest('in','object','context');
MethodTest::runTest('in','static','context');

其中,$arguments作为一个array传入。运行结果:

Calling object method 'runTest' in object context
Calling static method 'runTest' in static context

还要注意函数的作用域protected和private:

class TestMagicCallMethod {
  public function foo()
  {
    echo __METHOD__.PHP_EOL."<br>";
  }

  public function __call($method, $args)
  {
    echo __METHOD__.PHP_EOL."<br>";
    if(method_exists($this, $method))
    {
      $this->$method();
    }
  }
  
  protected function bar()
  {
    echo __METHOD__.PHP_EOL."<br>";
  }

  private function baz()
  {
    echo __METHOD__.PHP_EOL."<br>";
  }
}

$test  =  new TestMagicCallMethod();
$test->foo();
/**
 * Outputs:
 * TestMagicCallMethod::foo
 */

$test->bar();
/**
 * Outputs:
 * TestMagicCallMethod::__call
 * TestMagicCallMethod::bar
 */

$test->baz();
/**
 * Outputs:
 * TestMagicCallMethod::__call
 * TestMagicCallMethod::baz
 */

3.__get()和__set()

当试图读取一个对象并不存在的属性的时候被调用。

Note:我们可以用这个函数实现类似java中反射的各种操作。

class Test
{
  public function __get($key)
  {
   echo $key . " not exists";
  }
  public function __set($key,$value)
  {
   echo $key . " = ".$value;
  }
}

$t = new Test();
echo $t->name."<br>";
$t->name = "abc";

输出:
name not exists
name = abc

4. __toString()

 这个方法类似于java的toString()方法,当我们直接打印对象的时候回调用这个函数,函数必须返回一个string。

class Test
{
  private $name = "abc";
  private $age = 12;

  public function __toString()
  {
    return "name : $this->name, age : $this->age";
  }
}

$t = new Test();
echo $t;

输出:

name : abc, age : 12

PHP 相关文章推荐
聊天室php&amp;mysql(六)
Oct 09 PHP
一个PHP模板,主要想体现一下思路
Dec 25 PHP
php学习笔记 类的声明与对象实例化
Jun 13 PHP
PHP 字符串长度判断效率更高的方法
Mar 02 PHP
thinkPHP实现瀑布流的方法
Nov 29 PHP
php支付宝接口用法分析
Jan 04 PHP
Yii2主题(Theme)用法详解
Jul 23 PHP
PHP递归删除多维数组中的某个值
Apr 17 PHP
详解PHP处理字符串类似indexof的方法函数
Jun 11 PHP
php面向对象重点知识分享
Sep 27 PHP
Laravel5.1 框架Middleware中间件基本用法实例分析
Jan 04 PHP
PHP7 新增功能
Mar 09 PHP
PHP的魔术常量__METHOD__简介
Jul 08 #PHP
PHP中的插件机制原理和实例
Jul 08 #PHP
phpmailer在服务器上不能正常发送邮件的解决办法
Jul 08 #PHP
php去掉URL网址中带有PHPSESSID的配置方法
Jul 08 #PHP
PHP大批量插入数据库的3种方法和速度对比
Jul 08 #PHP
php发送get、post请求的6种方法简明总结
Jul 08 #PHP
PHP中对各种加密算法、Hash算法的速度测试对比代码
Jul 08 #PHP
You might like
PHP读MYSQL中文乱码的解决方法
2006/12/17 PHP
JS创建优美的页面滑动块效果 - Glider.js
2007/09/27 Javascript
js函数般调用正则
2008/04/08 Javascript
jquery 学习之二 属性(html()与html(val))
2010/11/25 Javascript
jquery绑定原理 简单解析与实现代码分享
2011/09/06 Javascript
html超链接打开窗口大小的方法
2013/03/05 Javascript
js控制淡入淡出示例代码
2013/11/12 Javascript
node.js中的buffer.toString方法使用说明
2014/12/14 Javascript
24款热门实用的jQuery插件推荐
2014/12/24 Javascript
JS实现的倒计时效果实例(2则实例)
2015/12/23 Javascript
利用css+原生js制作简单的钟表
2020/04/07 Javascript
Javascript中级语法快速入手
2016/07/30 Javascript
纯JS代码实现隔行变色鼠标移入高亮
2016/11/23 Javascript
Bootstrap标签页(Tab)插件使用方法
2017/03/21 Javascript
详解vue-cli 本地开发mock数据使用方法
2018/05/29 Javascript
js中的闭包实例展示
2018/11/01 Javascript
微信小程序实现左右列表联动
2020/05/19 Javascript
[53:49]LGD vs Fnatic 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
Django框架中数据的连锁查询和限制返回数据的方法
2015/07/17 Python
python导出chrome书签到markdown文件的实例代码
2017/12/27 Python
python批量下载网站马拉松照片的完整步骤
2018/12/05 Python
关于pytorch多GPU训练实例与性能对比分析
2019/08/19 Python
tensorflow实现训练变量checkpoint的保存与读取
2020/02/10 Python
基于Python的图像阈值化分割(迭代法)
2020/11/20 Python
详解解决jupyter不能使用pytorch的问题
2021/02/18 Python
中国跨境电商:Tomtop
2017/03/16 全球购物
LN-CC美国:伦敦时尚生活的缩影
2019/02/19 全球购物
枚举和一组预处理的#define有什么不同
2016/09/21 面试题
EJB的角色和三个对象
2015/12/31 面试题
室内设计自我鉴定
2013/10/15 职场文书
皮肤科医师岗位职责
2013/12/04 职场文书
中央空调节能方案
2014/06/15 职场文书
介绍长城的导游词
2015/01/30 职场文书
搞笑结婚保证书
2015/05/08 职场文书
商业计划书范文
2019/04/24 职场文书
2019大学毕业晚会主持词
2019/06/21 职场文书