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公用函数列表[正则]
Feb 22 PHP
php adodb介绍
Mar 19 PHP
PHP MySQL应用中使用XOR运算加密算法分享
Aug 28 PHP
谈谈关于php的优点与缺点
Apr 11 PHP
php生成图形验证码几种方法小结
Aug 15 PHP
PHP中使用虚代理实现延迟加载技术
Nov 05 PHP
php网站被挂木马后的修复方法总结
Nov 06 PHP
PHP基于GD库的图像处理方法小结
Sep 27 PHP
php  单例模式详细介绍及实现源码
Nov 05 PHP
Win7环境下Apache连接MySQL提示连接已重置的解决办法
May 09 PHP
php表单文件iframe异步上传实例讲解
Jul 26 PHP
PHP工厂模式简单实现方法示例
May 23 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
使用无限生命期Session的方法
2006/10/09 PHP
SMARTY学习手记
2007/01/04 PHP
提高php运行速度的一些小技巧分享
2012/07/03 PHP
thinkphp配置连接数据库技巧
2014/12/02 PHP
PHP实现json_decode不转义中文的方法
2017/05/20 PHP
jQuery的.live()和.die() 使用介绍
2011/09/10 Javascript
模拟多级复选框效果的jquery代码
2013/08/13 Javascript
setTimeout和setInterval的深入理解
2013/11/08 Javascript
javascript动态向网页中添加表格实现代码
2014/02/19 Javascript
js获得参数的getParameter使用示例
2014/02/26 Javascript
jQuery截取指定长度字符串的实现原理及代码
2014/07/01 Javascript
jquery中filter方法用法实例分析
2015/02/06 Javascript
JavaScript 面向对象与原型
2015/04/10 Javascript
jQuery实现的超链接提示效果示例【附demo源码下载】
2016/09/09 Javascript
AngularJS操作键值对象类似java的hashmap(填坑小结)
2016/11/12 Javascript
javascript中href和replace的比较(详解)
2016/11/25 Javascript
jQuery表格的维护和删除操作
2017/02/03 Javascript
JS图片预加载插件详解
2017/06/21 Javascript
详解使用create-react-app快速构建React开发环境
2018/05/16 Javascript
vue中实现左右联动的效果
2018/06/22 Javascript
深入Vue-Router路由嵌套理解
2018/08/13 Javascript
JS Object.preventExtensions(),Object.seal()与Object.freeze()用法实例分析
2018/08/25 Javascript
JS删除String里某个字符的方法
2021/01/06 Javascript
[48:44]2014 DOTA2国际邀请赛中国区预选赛5.21 TongFu VS HGT
2014/05/22 DOTA
itchat和matplotlib的结合使用爬取微信信息的实例
2017/08/25 Python
用Python中的turtle模块画图两只小羊方法
2019/04/09 Python
Win10下Python3.7.3安装教程图解
2019/07/08 Python
简单了解django索引的相关知识
2019/07/17 Python
德国运动营养和健身网上商店:Myprotein.de
2018/07/18 全球购物
顶岗实习接收函
2014/01/09 职场文书
幼儿园新学期寄语
2014/01/18 职场文书
5s推行计划书
2014/05/06 职场文书
获奖感言怎么写
2015/07/31 职场文书
Redis实现订单过期删除的方法步骤
2022/06/05 Redis
Apache SkyWalking 监控 MySQL Server 实战解析
2022/09/23 Servers
postgresql中如何执行sql文件
2023/05/08 PostgreSQL