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 相关文章推荐
PHP5 安装方法
Jan 15 PHP
php GD绘制24小时柱状图
Jun 28 PHP
PHP提取数据库内容中的图片地址并循环输出
Mar 21 PHP
php学习之 数组声明
Jun 09 PHP
关于PHP堆栈与列队的学习
Jun 21 PHP
php采用curl实现伪造IP来源的方法
Nov 21 PHP
php使用socket post数据到其它web服务器的方法
Jun 02 PHP
php中 ob_start等函数截取标准输出的方法
Jun 22 PHP
php array_values 返回数组的值实例详解
Nov 17 PHP
php面向对象的用户登录身份验证
Jun 08 PHP
php检测mysql表是否存在的方法小结
Jul 20 PHP
php设计模式之备忘模式分析【星际争霸游戏案例】
Mar 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
php5 apache 2.2 webservice 创建与配置(java)
2011/01/27 PHP
PHP中改变图片的尺寸大小的代码
2011/07/17 PHP
那些年一起学习的PHP(三)
2012/03/22 PHP
使用图灵api创建微信聊天机器人
2015/07/23 PHP
摘自织梦CMS的HTTP文件下载类
2015/08/08 PHP
PHP 计算至少是其他数字两倍的最大数的实现代码
2020/05/26 PHP
js动画效果制件让图片组成动画代码分享
2014/01/14 Javascript
javascript白色简洁计算器
2015/05/04 Javascript
使用Node.js为其他程序编写扩展的基本方法
2015/06/23 Javascript
javascript实现tab切换的两个实例
2015/11/05 Javascript
深入学习AngularJS中数据的双向绑定机制
2016/03/04 Javascript
jQuery实现带水平滑杆的焦点图动画插件
2016/03/08 Javascript
快速解决js动态改变dom元素属性后页面及时渲染的问题
2016/07/06 Javascript
原生JS取代一些JQuery方法的简单实现
2016/09/20 Javascript
原生ajax处理json格式数据的实例代码
2016/12/25 Javascript
Angular.js基础学习之初始化
2017/03/10 Javascript
AngularJS路由Ui-router模块用法示例
2017/05/29 Javascript
Bootstrap table使用方法记录
2017/08/23 Javascript
JS实现为动态添加的元素增加事件功能示例【基于事件委托】
2018/03/21 Javascript
vue--vuex详解
2019/04/15 Javascript
泛谈JS逻辑判断选择器 || &amp;&amp;
2019/05/24 Javascript
原生JS 实现的input输入时表格过滤操作示例
2019/08/03 Javascript
[01:01:29]2018DOTA2亚洲邀请赛 4.4 淘汰赛 VP vs Liquid 第一场
2018/04/05 DOTA
Python学习资料
2007/02/08 Python
python批量赋值操作实例
2018/10/22 Python
Python解决两个整数相除只得到整数部分的实例
2018/11/10 Python
Python 正则表达式匹配字符串中的http链接方法
2018/12/25 Python
Python使用itchat模块实现简单的微信控制电脑功能示例
2019/08/26 Python
pytorch使用tensorboardX进行loss可视化实例
2020/02/24 Python
django template实现定义临时变量,自定义赋值、自增实例
2020/07/12 Python
Python创建文件夹与文件的快捷方法
2020/12/08 Python
css3闪亮进度条效果实现思路及代码
2013/04/17 HTML / CSS
毕业生护理专业个人求职信范文
2014/01/04 职场文书
幼儿园亲子活动方案
2014/01/29 职场文书
学生会宣传部竞选稿
2015/11/21 职场文书
看完这篇文章获得一些java if优化技巧
2021/07/15 Java/Android