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合并数组array_merge函数运算符加号与的区别
Oct 31 PHP
PHP 时间日期操作实战
Aug 26 PHP
解析:php调用MsSQL存储过程使用内置RETVAL获取过程中的return值
Jul 03 PHP
使用PHP备份MYSQL数据的多种方法
Jan 15 PHP
php使用正则表达式提取字符串中尖括号、小括号、中括号、大括号中的字符串
Apr 05 PHP
百度实时推送api接口应用示例
Oct 21 PHP
PHP SPL标准库中的常用函数介绍
May 11 PHP
php投票系统之增加与删除投票(管理员篇)
Jul 01 PHP
php数据库的增删改查 php与javascript之间的交互
Aug 31 PHP
PHP基于phpqrcode类生成二维码的方法详解
Mar 14 PHP
PHP实现搜索时记住状态的方法示例
May 11 PHP
YII2框架中ActiveDataProvider与GridView的配合使用操作示例
Mar 18 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
非常不错的MySQL优化的8条经验
2008/03/24 PHP
JavaScript 事件记录使用说明
2009/10/20 Javascript
onsubmit阻止form表单提交与onclick的相关操作
2010/09/03 Javascript
IE8提示Invalid procedure call or argument 异常的解决方法
2012/09/30 Javascript
很好用的js日历算法详细代码
2013/03/07 Javascript
JavaScript1.6数组新特性介绍以及JQuery的几个工具方法
2013/12/06 Javascript
jQuery处理XML文件的几种方法
2016/06/14 Javascript
第四篇Bootstrap网格系统偏移列和嵌套列
2016/06/21 Javascript
javascript判断firebug是否开启的方法
2016/11/23 Javascript
如何解决vue与传统jquery插件冲突
2017/03/20 Javascript
JS实现加载和读取XML文件的方法详解
2017/04/24 Javascript
jQuery实现在HTML文档加载完毕后自动执行某个事件的方法
2017/05/08 jQuery
JS实现静态页面搜索并高亮显示功能完整示例
2017/09/19 Javascript
JS设计模式之数据访问对象模式的实例讲解
2017/09/30 Javascript
深入研究React中setState源码
2017/11/17 Javascript
Bootstrap实现可折叠分组侧边导航菜单
2018/03/07 Javascript
vue获取当前点击的元素并传值的实例
2018/03/09 Javascript
vue中设置、获取、删除cookie的方法
2018/09/21 Javascript
webpack4.x CommonJS模块化浅析
2018/11/09 Javascript
JS实现判断有效的数独算法示例
2019/02/25 Javascript
详解vue为什么要求组件模板只能有一个根元素
2019/07/22 Javascript
详解如何在Javascript和Sass之间共享变量
2019/11/13 Javascript
JavaScript, select标签元素左右移动功能实现
2020/05/14 Javascript
Javascript实现贪吃蛇小游戏(含详细注释)
2020/10/23 Javascript
使用Python下载Bing图片(代码)
2013/11/07 Python
python实现ipsec开权限实例
2014/11/11 Python
Python中你应该知道的一些内置函数
2017/03/31 Python
python使用PIL实现多张图片垂直合并
2019/01/15 Python
使用Keras画神经网络准确性图教程
2020/06/15 Python
大唐电信科技股份有限公司java工程师面试经历
2016/12/09 面试题
李敖北大演讲稿
2014/05/24 职场文书
平安建设汇报材料
2014/12/29 职场文书
入党积极分子培养人意见
2015/06/02 职场文书
怎样写家长意见
2015/06/04 职场文书
聘任书范文大全
2015/09/21 职场文书
Python 把两层列表展开平铺成一层(5种实现方式)
2021/04/07 Python