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 之入门篇
Dec 04 PHP
shopex主机报错误请求解决方案(No such file or directory)
Dec 27 PHP
基于wordpress主题制作的具体实现步骤
May 10 PHP
PHP内核探索:变量概述
Jan 30 PHP
PHP生成网站桌面快捷方式代码分享
Oct 11 PHP
PHP中的替代语法介绍
Jan 09 PHP
浅谈php命令行用法
Feb 04 PHP
Laravel 5框架学习之用户认证
Apr 09 PHP
php计算整个mysql数据库大小的方法
Jun 19 PHP
PHP 5.6.11 访问SQL Server2008R2的几种情况详解
Aug 08 PHP
Laravel5.1 框架Request请求操作常见用法实例分析
Jan 04 PHP
PHP执行系统命令函数实例讲解
Mar 03 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
10条PHP编程习惯助你找工作
2008/09/29 PHP
用PHP读取超大文件的实例代码
2012/04/01 PHP
可以保证单词完整性的PHP英文字符串截取代码分享
2014/07/15 PHP
javascript js cookie的存储,获取和删除
2007/12/29 Javascript
JavaScript 图片预览效果 推荐
2009/12/22 Javascript
Extjs中DisplayField的日期或者数字格式化扩展
2010/09/03 Javascript
计算世界完全对称日的js代码,粗糙版
2011/11/04 Javascript
JS和JQUERY获取页面大小,滚动条位置,元素位置(示例代码)
2013/12/14 Javascript
jQuery 1.9.1源码分析系列(十)事件系统之绑定事件
2015/11/19 Javascript
谈谈我对JavaScript DOM事件的理解
2015/12/18 Javascript
微信小程序 图片加载(本地,网路)实例详解
2017/03/10 Javascript
JavaScript中in和hasOwnProperty区别详解
2017/08/04 Javascript
Vue DevTools调试工具的使用
2017/12/05 Javascript
node的process以及child_process模块学习笔记
2018/03/06 Javascript
JavaScript EventEmitter 背后的秘密 完整版
2018/03/29 Javascript
前端axios下载excel文件(二进制)的处理方法
2018/07/31 Javascript
Vue项目自动转换 px 为 rem的实现方法
2018/10/29 Javascript
微信小程序蓝牙连接小票打印机实例代码详解
2019/06/03 Javascript
[52:32]完美世界DOTA2联赛PWL S2 Magma vs LBZS 第三场 11.18
2020/11/18 DOTA
python实现进程间通信简单实例
2014/07/23 Python
Windows下为Python安装Matplotlib模块
2015/11/06 Python
python实现RSA加密(解密)算法
2016/02/17 Python
python 中字典嵌套列表的方法
2018/07/03 Python
浅析python继承与多重继承
2018/09/13 Python
Pycharm新手教程(只需要看这篇就够了)
2019/06/18 Python
python next()和iter()函数原理解析
2020/02/07 Python
css3实现顶部社会化分享按钮示例
2014/05/06 HTML / CSS
Scholastic父母商店:儿童书籍
2017/01/01 全球购物
C语言编程题
2015/03/09 面试题
博士学位自我鉴定范文
2013/12/26 职场文书
医药销售自我评价200字
2014/09/11 职场文书
党的群众路线教育实践活动对照检查材料思想汇报
2014/09/19 职场文书
2015秋季开学典礼演讲稿
2015/07/16 职场文书
通讯稿格式及范文
2015/07/22 职场文书
SQL优化老出错,那是你没弄明白MySQL解释计划用法
2021/11/27 MySQL
用Python仅20行代码编写一个简单的端口扫描器
2022/04/08 Python