PHP中的魔术方法总结和使用实例


Posted in PHP onMay 11, 2015

魔术方法是PHP面向对象中特有的特性。它们在特定的情况下被触发,都是以双下划线开头,你可以把它们理解为钩子,利用模式方法可以轻松实现PHP面向对象中重载(Overloading即动态创建类属性和方法)。魔术方法很多还是成对出现的,以下列出目前PHP中所有的模式方法。

1.__construct,__destruct

__constuct构建对象的时被调用;
__destruct明确销毁对象或脚本结束时被调用;

2.__get,__set

__set当给不可访问或不存在属性赋值时被调用
__get读取不可访问或不存在属性时被调用

3.__isset,__unset

__isset对不可访问或不存在的属性调用isset()或empty()时被调用
__unset对不可访问或不存在的属性进行unset时被调用

4.__call,__callStatic

__call调用不可访问或不存在的方法时被调用
__callStatic调用不可访问或不存在的静态方法时被调用

5.__sleep,__wakeup

__sleep当使用serialize时被调用,当你不需要保存大对象的所有数据时很有用
__wakeup当使用unserialize时被调用,可用于做些对象的初始化操作

6.__clone

进行对象clone时被调用,用来调整对象的克隆行为

7.__toString

当一个类被转换成字符串时被调用

8.__invoke

当以函数方式调用对象时被调用

9.__set_state

当调用var_export()导出类时,此静态方法被调用。用__set_state的返回值做为var_export的返回值。

10.__debuginfo

当调用var_dump()打印对象时被调用(当你不想打印所有属性)适用于PHP5.6版本

PHP魔术方法使用实例如下:

<?php
 
class Magic
{
  public $var = 'test';
 
  //构造函数,在创建对象的时候调用
  public function __construct()
  {
    echo '__construct called'.PHP_EOL;
  }
 
  //某个对象的引用都被删除、对象被销毁、调用exit()后、脚本关闭时被调用
  public function __destruct()
  {
    echo '__destruct called'.PHP_EOL;
  }
 
  //当给不可访问或不存在属性赋值时被调用
  public function __set($name, $value)
  {
    echo $name.'-'.$value;
    echo '__set called'.PHP_EOL;
  }
 
  //读取不可访问或不存在属性时被调用
  public function __get($name)
  {
    echo $name;
    echo '__get called'.PHP_EOL;
  }
 
  //调用不可访问或不存在的方法时被调用
  public function __call($name, $arguments)
  {
    echo $name . '-' . implode(',', $arguments);
    echo '__call called'.PHP_EOL;
  }
 
  //调用不可访问或不存在的静态方法时被调用
  public static function __callStatic($name, $arguments)
  {
    echo $name . '-' . implode(',', $arguments);
    echo '__callStatic called'.PHP_EOL;
  }
 
  //对不可访问或不存在的属性调用isset()或empty()时被调用
  public function __isset($name)
  {
    echo $name;
    echo '__isset called'.PHP_EOL;
    return true;
  }
 
  //对不可访问或不存在的属性进行unset时被调用
  public function __unset($name)
  {
    echo $name;
    echo '__unset called'.PHP_EOL;
  }
 
  //serialize时被调用,当你不需要保存大对象的所有数据时很有用
  public function __sleep()
  {
    echo '__sleep called'.PHP_EOL;
    return array('var1111111111');
  }
 
  //unserialize时被调用,可用于做些对象的初始化操作
  public function __wakeup()
  {
    echo '__wakeup called'.PHP_EOL;
    $this->var = 'test after wakeup';
  }
 
  //当一个类被转换成字符串时被调用
  public function __toString()
  {
    return '__toString called'.PHP_EOL;
  }
 
  //进行对象clone时被调用,用来调整对象的克隆行为
  public function __clone()
  {
    echo '__clone called'.PHP_EOL;
  }
 
  //当以函数方式调用对象时被调用
  public function __invoke()
  {
    echo '__invoke called'.PHP_EOL;
  }
 
  //当调用var_export()导出类时,此静态方法被调用。用__set_state的返回值做为var_export的返回值。
  public static function __set_state($arr)
  {
    return '__set_state called'.PHP_EOL;
  }
 
  //当调用var_dump()打印对象时被调用(当你不想打印所有属性)适用于PHP5.6版本
  public function __debuginfo($arr)
  {
    echo '__debuginfo called'.PHP_EOL;
    return array(
      'var' => 'test fro __debuginfo'
    );
  }
}
 
$m = new Magic(); //__construct()被调用
$m->not_exist_property = test; //__set()被调用
echo $m->not_exist_property;//__get()被调用
$m->abc(1,2,3); //__call()被调用
echo isset($m->not_exist_property); //__isset()被调用,返回bool值
unset($m->not_exist_property); //__unset()被调用
echo $tmp = serialize($m); //__sleep()被调用
unserialize($tmp); //__wakeup()被调用
$m1 = clone $m; //__clone()被调用,对象默认是引用传递,使用clone关键词则可实现对象复制
$m(); //__invoke()
eval( '$m2 = ' . var_export ( $m , true ) . ';' );var_dump($m2);
var_dump($m);
//最后__destruct()被调用
 
/*
结果:
__construct called
not_exist_property-test__set called
not_exist_property__get called
abc-1,2,3__call called
not_exist_property__isset called
1not_exist_property__unset called
__sleep called
O:5:"Magic":1:{s:13:"var1111111111";N;}__wakeup called
__destruct called
__clone called
__invoke called
string(20) "__set_state called
"
class Magic#1 (1) {
 public $var =>
 string(4) "test"
}
__destruct called
__destruct called
 
 
*/
PHP 相关文章推荐
Mysql中分页查询的两个解决方法比较
May 02 PHP
PHP二维数组排序的3种方法和自定义函数分享
Apr 09 PHP
PHP过滤黑名单关键字的方法
Dec 01 PHP
php相对当前文件include其它文件的方法
Mar 13 PHP
WordPress中获取页面链接和标题的相关PHP函数用法解析
Dec 17 PHP
thinkPHP中配置的读取与C方法详解
Dec 05 PHP
PHP面向对象五大原则之单一职责原则(SRP)详解
Apr 04 PHP
PHP实现用户登录的案例代码
May 10 PHP
PHP进阶学习之类的自动加载机制原理分析
Jun 18 PHP
thinkPHP事务操作简单案例分析
Oct 17 PHP
Laravel6.18.19如何优雅的切换发件账户
Jun 14 PHP
基于PHP实现解密或加密Cloudflar邮箱保护
Jun 24 PHP
php基于curl扩展制作跨平台的restfule 接口
May 11 #PHP
PHP SPL标准库中的常用函数介绍
May 11 #PHP
PHP中的类型约束介绍
May 11 #PHP
PHP SPL标准库之接口(Interface)详解
May 11 #PHP
PHP SPL标准库之文件操作(SplFileInfo和SplFileObject)实例
May 11 #PHP
PHP设计模式之适配器模式代码实例
May 11 #PHP
Mac环境下php操作mysql数据库的方法分享
May 11 #PHP
You might like
PHP初学者头疼问题总结
2006/07/08 PHP
一个ORACLE分页程序,挺实用的.
2006/10/09 PHP
PHP简洁函数(PHP简单明了函数语法)
2012/06/10 PHP
PHP 使用pcntl和libevent 实现Timer功能
2013/10/27 PHP
PHP实现的简易版图片相似度比较
2015/01/07 PHP
PHP实现通过strace定位故障原因的方法
2018/04/29 PHP
PHP实现通过CURL上传文件功能示例
2018/05/30 PHP
如何判断图片地址是否失效
2007/02/02 Javascript
JQuery实现表格中相同单元格合并示例代码
2013/06/26 Javascript
Jquery 实现弹出层插件
2015/01/28 Javascript
JavaScript中switch语句的用法详解
2015/06/03 Javascript
ANGULARJS中使用JQUERY分页控件
2015/09/16 Javascript
Jquery对新插入的节点 绑定Click事件失效的解决方法
2016/06/02 Javascript
BootStrap.css 在手机端滑动时右侧出现空白的原因及解决办法
2016/06/07 Javascript
jQuery插件HighCharts实现的2D对数饼图效果示例【附demo源码下载】
2017/03/09 Javascript
AngularJS+Bootstrap3多级导航菜单的实现代码
2017/08/16 Javascript
实现div滚动条默认最底部以及默认最右边的示例代码
2017/11/15 Javascript
JS实现网页抢购功能(触发,终止脚本)
2017/11/27 Javascript
jQuery AJAX与jQuery事件的分析讲解
2019/02/18 jQuery
vue实现绑定事件的方法实例代码详解
2019/06/20 Javascript
Python 除法小技巧
2008/09/06 Python
基于python的汉字转GBK码实现代码
2012/02/19 Python
Python编写电话薄实现增删改查功能
2016/05/07 Python
linecache模块加载和缓存文件内容详解
2018/01/11 Python
Python 统计位数为偶数的数字代码详解
2020/03/15 Python
使用python采集Excel表中某一格数据
2020/05/14 Python
Python用access判断文件是否被占用的实例方法
2020/12/17 Python
Django url 路由匹配过程详解
2021/01/22 Python
Html5新标签解释及用法
2012/02/17 HTML / CSS
最热门的自我评价
2013/12/30 职场文书
田径运动会开幕式及主持词
2014/03/28 职场文书
好媳妇事迹材料
2014/12/24 职场文书
小学运动会宣传稿
2015/07/23 职场文书
《秋思》教学反思
2016/02/23 职场文书
导游词之张家口
2019/12/13 职场文书
MySQL中使用or、in与union all在查询命令下的效率对比
2021/05/26 MySQL