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将向Java靠拢
Oct 09 PHP
写一个用户在线显示的程序
Oct 09 PHP
PR值查询 | PageRank 查询
Dec 20 PHP
MySql中正则表达式的使用方法描述
Jul 30 PHP
配置php.ini实现PHP文件上传功能
Nov 27 PHP
PHP中文编码小技巧
Dec 25 PHP
Laravel 5框架学习之表单
Apr 08 PHP
smarty中常用方法实例总结
Aug 07 PHP
php基于curl实现的股票信息查询类实例
Nov 11 PHP
php实现等比例压缩图片
Jul 26 PHP
PHP unset函数原理及使用方法解析
Aug 14 PHP
php慢查询日志和错误日志使用详解
Feb 27 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
用Simple Excel导出xls实现方法
2012/12/06 PHP
基于PHP的简单采集数据入库程序
2014/07/30 PHP
Yii2框架使用计划任务的方法
2016/05/25 PHP
PHP使用PHPExcel删除Excel单元格指定列的方法
2016/07/06 PHP
Javascript调用C#代码
2011/01/17 Javascript
jquery的ajax和getJson跨域获取json数据的实现方法
2014/02/04 Javascript
Javascript中的几种URL编码方法比较
2015/01/23 Javascript
JavaScript中使用Math.floor()方法对数字取整
2015/06/15 Javascript
js实现密码强度检测【附示例】
2016/03/30 Javascript
jqGrid用法汇总(全经典)
2016/06/28 Javascript
微信js-sdk上传与下载图片接口用法示例
2016/10/12 Javascript
js中通过getElementsByName访问name集合对象的方法
2016/10/31 Javascript
基于jQuery实现手风琴菜单、层级菜单、置顶菜单、无缝滚动效果
2017/07/20 jQuery
promise处理多个相互依赖的异步请求(实例讲解)
2017/08/03 Javascript
MUI顶部选项卡的用法(tab-top-webview-main)详解
2017/10/08 Javascript
JavaScript调用模式与this关键字绑定的关系
2018/04/21 Javascript
javascript验证form表单数据的案例详解
2019/03/25 Javascript
vue-froala-wysiwyg 富文本编辑器功能
2019/09/19 Javascript
JS表单验证插件之数据与逻辑分离操作实例分析【策略模式】
2020/05/01 Javascript
vue实现输入框自动跳转功能
2020/05/20 Javascript
深入理解Python对Json的解析
2017/02/14 Python
python构建深度神经网络(DNN)
2018/03/10 Python
详解django+django-celery+celery的整合实战
2019/03/19 Python
网易有道2017内推编程题 洗牌(python)
2019/06/19 Python
Python中的延迟绑定原理详解
2019/10/11 Python
python模拟斗地主发牌
2020/04/22 Python
环境工程大学生自荐信
2013/10/21 职场文书
通信研究生自荐信
2014/02/01 职场文书
军训感想500字
2014/02/20 职场文书
青年志愿者活动总结
2014/04/26 职场文书
学校节能宣传周活动总结
2014/07/09 职场文书
2014五年级班主任工作总结
2014/12/05 职场文书
房产公证书
2015/01/23 职场文书
个人自荐书范文
2015/03/09 职场文书
Python实现天气查询软件
2021/06/07 Python
教你win10系统中APPCRASH事件问题解决方法
2022/07/15 数码科技