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 相关文章推荐
用PHP读取flv文件的播放时间长度
Sep 03 PHP
GBK的页面输出JSON格式的php函数
Feb 16 PHP
Cakephp 执行主要流程
Mar 24 PHP
PHP中将数组转成XML格式的实现代码
Aug 08 PHP
php全排列递归算法代码
Oct 09 PHP
Laravel框架数据库CURD操作、连贯操作总结
Sep 03 PHP
PHP图片处理之图片旋转和图片翻转实例
Nov 19 PHP
PHP、Python和Javascript的装饰器模式对比
Feb 03 PHP
举例讲解PHP面对对象编程的多态
Aug 12 PHP
thinkphp表单上传文件并将文件路径保存到数据库中
Jul 28 PHP
php网页版聊天软件实现代码
Aug 12 PHP
Yii框架学习笔记之应用组件操作示例
Nov 13 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输出XML到页面的3种方法详解
2013/06/06 PHP
探讨如何在php168_cms中提取验证码
2013/06/08 PHP
jquery+php实现导出datatables插件数据到excel的方法
2015/07/06 PHP
浅谈php中变量的数据类型判断函数
2017/03/04 PHP
JavaScript类和继承 constructor属性
2010/03/04 Javascript
JavaScript原型继承之基础机制分析
2011/08/26 Javascript
jQuery 阴影插件代码分享
2012/01/09 Javascript
js循环改变div颜色具体方法
2013/06/25 Javascript
JS保留两位小数 四舍五入函数的小例子
2013/11/20 Javascript
按下Enter焦点移至下一个控件的实现js代码
2013/12/11 Javascript
JQuery与JS里submit()的区别示例介绍
2014/02/17 Javascript
jQuery老黄历完整实现方法
2015/01/16 Javascript
基于BootStrap Metronic开发框架经验小结【二】列表分页处理和插件JSTree的使用
2016/05/12 Javascript
jQuery插件 Jqplot图表实例
2016/06/18 Javascript
利用select实现年月日三级联动的日期选择效果【推荐】
2016/12/13 Javascript
详解vue表单——小白速看
2018/04/08 Javascript
vue 解决文本框被键盘遮住的问题
2019/11/06 Javascript
vue二选一tab栏切换新做法实现
2021/01/19 Vue.js
Python判断文件和文件夹是否存在的方法
2015/05/21 Python
Python实现的大数据分析操作系统日志功能示例
2019/02/11 Python
python安装和pycharm环境搭建设置方法
2020/05/27 Python
Python描述数据结构学习之哈夫曼树篇
2020/09/07 Python
python实现图片,视频人脸识别(opencv版)
2020/11/18 Python
python爬虫今日热榜数据到txt文件的源码
2021/02/23 Python
CSS3实现自定义Checkbox特效实例代码
2017/04/24 HTML / CSS
Etam艾格英国官网:法国著名女装品牌
2019/04/15 全球购物
Araks官网:纽约内衣品牌
2020/10/15 全球购物
J2EE模式面试题
2016/10/11 面试题
《第一次抱母亲》教学反思
2014/04/16 职场文书
让生命充满爱演讲稿
2014/05/10 职场文书
党的群众路线教育实践活动通讯稿
2014/09/10 职场文书
单位计划生育责任书
2015/05/09 职场文书
2015年质量管理工作总结范文
2015/05/18 职场文书
离职证明格式样本
2015/06/12 职场文书
Java框架入门之简单介绍SpringBoot框架
2021/06/18 Java/Android
python微信智能AI机器人实现多种支付方式
2022/04/12 Python