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 相关文章推荐
PHP4(windows版本)中的COM函数
Oct 09 PHP
PHP与MySQL开发中页面出现乱码的一种解决方法
Jul 29 PHP
实用函数9
Nov 08 PHP
用php实现的下载css文件中的图片的代码
Feb 08 PHP
在Win7 中为php扩展配置Xcache
Oct 08 PHP
thinkphp 验证码 的使用小结
May 07 PHP
php数据库的增删改查 php与javascript之间的交互
Aug 31 PHP
PHP中register_shutdown_function函数的基础介绍与用法详解
Nov 28 PHP
PHP内置函数生成随机数实例
Jan 18 PHP
PHP关于foreach复制知识点总结
Jan 28 PHP
解决laravel groupBy 对查询结果进行分组出现的问题
Oct 09 PHP
php+ajax实现文件切割上传功能示例
Mar 03 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
在mysql数据库原有字段后增加新内容
2009/11/26 PHP
php中根据某年第几天计算出日期年月日的代码
2011/02/24 PHP
PHP系列学习之日期函数使用介绍
2012/08/18 PHP
php利用cookie实现自动登录的方法
2014/12/10 PHP
PHP实现即时输出、实时输出内容方法
2015/05/27 PHP
教大家制作简单的php日历
2015/11/17 PHP
详解Yii2.0使用AR联表查询实例
2017/06/16 PHP
PHP基于双向链表与排序操作实现的会员排名功能示例
2017/12/26 PHP
windows 2008r2+php5.6.28环境搭建详细过程
2019/06/18 PHP
关于JavaScript的gzip静态压缩方法
2007/01/05 Javascript
javascript判断单选框或复选框是否选中方法集锦
2007/04/04 Javascript
表格 隔行换色升级版
2009/11/07 Javascript
js实现在字符串中提取数字
2013/11/05 Javascript
jQuery判断元素上是否绑定了指定事件的方法
2015/03/17 Javascript
整理关于Bootstrap警示框的慕课笔记
2017/03/29 Javascript
angular directive的简单使用总结
2017/05/24 Javascript
使用json-server简单完成CRUD模拟后台数据的方法
2018/07/12 Javascript
vue实现多组关键词对应高亮显示功能
2019/07/25 Javascript
vue 解决兄弟组件、跨组件深层次的通信操作
2020/07/27 Javascript
python处理cookie详解
2014/02/07 Python
Python可变参数函数用法实例
2015/07/07 Python
Flask数据库迁移简单介绍
2017/10/24 Python
python 实现快速生成连续、随机字母列表
2019/11/28 Python
html5 拖拽上传图片实例演示
2013/04/01 HTML / CSS
New Balance德国官方网站:购买鞋子和服装
2019/08/31 全球购物
PHP面试题集
2016/12/18 面试题
绿化工程实施方案
2014/03/17 职场文书
幼儿园中班上学期评语
2014/04/18 职场文书
三月学雷锋月活动总结
2014/04/28 职场文书
幼儿园2014年度工作总结
2014/11/10 职场文书
2015年公民道德宣传日活动总结
2015/03/23 职场文书
房贷工资证明范本
2015/06/12 职场文书
2015暑期社会实践通讯稿
2015/07/18 职场文书
安全生产会议制度
2015/08/06 职场文书
2016先进工作者事迹材料
2016/02/25 职场文书
Python函数式编程中itertools模块详解
2021/09/15 Python