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 高手之路(二)
Oct 09 PHP
php设计模式 Facade(外观模式)
Jun 26 PHP
php中拷贝构造函数、赋值运算符重载
Jul 25 PHP
php读取excel文件的简单实例
Aug 26 PHP
php截取中文字符串不乱码的方法
Dec 25 PHP
去除php注释和去除空格函数分享
Mar 13 PHP
ThinkPHP3.1新特性之多层MVC的支持
Jun 19 PHP
PHP开发框架kohana中处理ajax请求的例子
Jul 14 PHP
PHP里的单例类写法实例
Jun 25 PHP
Yii2.0预定义的别名功能小结
Jul 04 PHP
PHP7安装Redis扩展教程【Linux与Windows平台】
Sep 30 PHP
PHP使用OB缓存实现静态化功能示例
Mar 23 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和javascript之间变量的传递实现代码
2012/12/19 PHP
如何解决CI框架的Disallowed Key Characters错误提示
2013/07/05 PHP
完美解决phpdoc导出文档中@package的warning及Error的错误
2016/05/17 PHP
php实现获取近几日、月时间示例
2019/07/06 PHP
laravel框架语言包拓展实现方法分析
2019/11/22 PHP
JS加ASP二级域名转向的代码
2007/05/17 Javascript
基于jQuery选择器的整理集合
2013/04/26 Javascript
JS Date函数整理方便使用
2013/10/23 Javascript
Js判断参数(String,Array,Object)是否为undefined或者值为空
2013/11/04 Javascript
jQuery的cookie插件实现保存用户登陆信息
2014/04/15 Javascript
node.js中的fs.createReadStream方法使用说明
2014/12/17 Javascript
jquery.map()方法的使用详解
2015/07/09 Javascript
Node.js实现兼容IE789的文件上传进度条
2016/09/02 Javascript
深入理解NodeJS 多进程和集群
2018/10/17 NodeJs
jQuery添加新内容的四个常用方法分析【append,prepend,after,before】
2019/03/19 jQuery
vue中npm包全局安装和局部安装过程
2019/09/03 Javascript
Python递归遍历列表及输出的实现方法
2015/05/19 Python
python3使用PyMysql连接mysql数据库实例
2017/02/07 Python
Python数据分析库pandas基本操作方法
2018/04/08 Python
python2与python3共存问题的解决方法
2018/09/18 Python
Pandas DataFrame 取一行数据会得到Series的方法
2018/11/10 Python
python使用sessions模拟登录淘宝的方式
2019/08/16 Python
python 画出使用分类器得到的决策边界
2019/08/21 Python
python+jinja2实现接口数据批量生成工具
2019/08/28 Python
Windows10下Tensorflow2.0 安装及环境配置教程(图文)
2019/11/21 Python
pycharm 实现调试窗口恢复
2021/02/05 Python
html5使用window.postMessage进行跨域实现数据交互的一次实战
2021/02/24 HTML / CSS
阿根廷在线宠物商店:Puppis
2018/03/23 全球购物
法学专业本科生自荐信范文
2013/12/17 职场文书
高中生职业规划范文
2014/03/09 职场文书
学校开学标语
2014/10/06 职场文书
大学生毕业评语
2014/12/31 职场文书
2015年控辍保学工作总结
2015/05/18 职场文书
优秀学生主要事迹怎么写
2015/11/04 职场文书
2016年“六一儿童节”校园广播稿
2015/12/17 职场文书
Redis实战高并发之扣减库存项目
2022/04/14 Redis