上文中介绍了非常常用并且也是面试时的热门魔术方法,而这篇文章中的所介绍的或许并不是那么常用,但绝对是加分项。当你能准确地说出这些方法及作用的时候,相信对方更能对你刮目相看。

__sleep()与__wakeup()

字面上的意思很好玩,睡觉和起床。它们分别对应着serialize()和unserialize()方法,也就是序列化和反序列化时会触发这两个魔术方法。

这里需要注意的是,__sleep()需要返回一个数组,而这个数组对应着类中的属性名。通常来说,它们可以在序列化前进行数据清理工作,或者反序列化前进行数据的预处理工作。比如序列化前关闭数据库连接或者反序列化前打开数据库连接。

public function __sleep()
{
echo '===sleep===' . PHP_EOL;
echo '调用serialize()时来找我,先睡一会的' . PHP_EOL;
echo '===unset===' . PHP_EOL;
return ['a'];
} public function __wakeup()
{
echo '===wakeup===' . PHP_EOL;
echo '调用unserialize()时来找我,起床吧' . PHP_EOL;
echo '===wakeup===' . PHP_EOL;
}

__toString()

顾名思义,这个方法通过返回一个字符串,实现对象的打印。如果没有实现这个方法,我们直接使用echo是无法打印对象的,会报错。当实现了这个魔术方法后,直接使用echo或者print等方法就可以进入这个魔术方法中,并打印出该方法中返回的内容。

public function __toString()
{
echo '===toString===' . PHP_EOL;
echo '调用echo、print时会使用我' . PHP_EOL;
echo '===toString===' . PHP_EOL;
return '打印出来看看吧';
}

当然,它也能实现对象转换到字符串,如在字符串拼接的时候,如:$obj = new Object(); $a = 'this is ' . $obj;这样使用。

__invoke()

很有意思的一个魔术方法,它的作用是将对象当做方法使用时会调用这个魔术方法。什么意思呢?比如:$obj = new Object();,然后直接$obj();

这时,就会进入这个魔术方法。那么有什么用呢?对于闭包以及反射来说,这个魔术方法有不可替代的作用。将来我们会在别的文章中进行详细说明。

public function __invoke()
{
echo '===invoke===' . PHP_EOL;
echo '把类当方法使用时就进这里了' . PHP_EOL;
echo '===invoke===' . PHP_EOL;
}

__clone()

使用clone关键字进行对象的复制时,就会调用这个魔术方法。其实就是原型模式的实现。在原型模式的相关文章中我们再来详细说明。

public function __clone()
{
echo '===clone===' . PHP_EOL;
echo '复制类的时候我就发挥作用了' . PHP_EOL;
echo '===clone===' . PHP_EOL;
}

__set_state()与__debugInfo()

真的是神奇的PHP语法,最后这两个魔术方法一个是用的下划线命名,一个是用的小驼峰。实在无力吐槽~~

这两个方法对应的是var_export()和var_dump()方法在使用时的调用。一般是在调试时使用,其实非常类似于__toString()方法。

public static function __set_state($an_array)
{
echo '===set_state===' . PHP_EOL;
echo '使用var_export()的时候使用调用我哦' . PHP_EOL;
echo '===set_state===' . PHP_EOL;
$m = new PHPMagic();
$m->var1 = 111;
$m->var2 = 222;
return $m;
} public function __debugInfo()
{
echo '===debugInfo===' . PHP_EOL;
echo '使用var_dump()的时候就是我来啦' . PHP_EOL;
echo '===debugInfo===' . PHP_EOL;
return [
'var1' => $this->var1,
'var2' => $this->var2,
];
}

通过两篇文章,我们熟悉了PHP所定义的这些魔术方法。在这里需要特别注意的是,PHP中将所有以__两个下划线开头的方法做为魔术方法的保留命名。所以在定义类方法的时候,不要使用两个下划线开头的方法名。

文档参考:https://www.php.net/manual/zh/language.oop5.magic.php

完整代码:https://github.com/zhangyue0503/php/blob/master/newblog/PHPMagic.php

关注公众号:【硬核项目经理】获取最新文章

添加微信/QQ好友:【xiaoyuezigonggong/149844827】免费得PHP、项目管理学习资料

知乎、公众号、抖音、头条搜索【硬核项目经理】

B站ID:482780532

PHP的那些魔术方法(二)的更多相关文章

  1. php预定义变量,超全局变量,魔术方法,特殊函数变量使用

    <?php /* * 本代码全部为测试函数代码,部分注释和写实例 * * 修改php.ini variables_order=”EGPCS” * 请注意$_REQUEST在优先级传参的时候会造成 ...

  2. PHP其它常用函数;<<<面向对象(OPP)的三大特性:封装、继承、加态:>>> <----面试题 ;构造方法、析构方法,魔术方法、set、get方法;静态;抽象类;接口

    PHP其它常用函数:     赋值:$r->name = "元素";      取值: echo $r->name;  count()   计算数组中的元素数目或对象中 ...

  3. 面向对象与面向过程 $this的注意事项和魔术方法set和get

    一.面向对象与面向过程的区别: 二者都是一种思想,面向对象是相对于面向过程而言的.面向过程,强调的是功能行为.面向对象,将功能封装进对象,强调具备了功能的对象.面向对象更加强调运用人类在日常的思维逻辑 ...

  4. [python]魔术方法

    一.初始化: 1.__new__方法,初始化过程中第一个用到的方法(用处不大). 2.之后,__init__方法,构造方法. 3.最后,在对象回收时,调用__del__方法.如果解释器退出时,对象还存 ...

  5. PHP中的面向对象OOP中的魔术方法

    一.什么是魔术方法: PHP为我们提供了一系列用__开头的函数,这些函数无需自己手动调用,会在合适的时机自动调用,这类函数称为魔术函数.例如: function __construct(){} 在ne ...

  6. Python 面向对象(四) 反射及其魔术方法

    反射 reflection 也有人称之为自省 作用: 运行时获取.添加对象的类型定义信息,包括类 内建方法: getattr(object, name[, default])   返回object对象 ...

  7. Python 面向对象(三) 魔术方法

    __getitem__ 在对实例或对象使用索引访问时调用,self[key]__dir__ 收集当前模块的信息,包括继承自其它基类(包括object类)的属性和方法 __new 定义如何创建实例__i ...

  8. 潭州课堂25班:Ph201805201 第十一课 继承,多继承和魔术方法,属性和方法 (课堂笔记)

    继承: class p : cls_name = 'p' def __init__(self): print('正在实例化') def __del__(self): print('正在销毁') cla ...

  9. PHP的魔术方法

    PHP中把以两个下划线__开头的方法称为魔术方法(Magic methods) 魔术方法包括: __construct(),类的构造函数 __destruct(),类的析构函数 __call(),在对 ...

随机推荐

  1. myvimrc

    set nocompatible execute pathogen#infect() call pathogen#helptags() call pathogen#incubate() imap jk ...

  2. 暴力破解 安鸾 Writeup

    前三题可以使用hydra进行破解 hydra使用教程 https://www.cnblogs.com/zhaijiahui/p/8371336.html D:\soft\hydra-windows&g ...

  3. 某次无中生有的getshell过程

    0x01 写在前面 某次对目标的渗透中,发现了疑似前台上传漏洞,反复测试后无法成功利用,多方探寻最终成功getshell的过程. 0x02 信息收集 这次的目标是一个APP分发平台,对这一类的网站接触 ...

  4. [论文阅读] ALM-HCS(高对比场景自适应对数映射)

    [论文阅读] ALM-HCS(高对比场景自适应对数映射) 文章: Adaptive Logarithmic Mapping for Displaying High Contrast Scenes 1. ...

  5. SQL 练习40

    按照出生日期来计算学生的年龄信息 IF OBJECT_ID('GetStudentAge','FN') IS NOT NULL DROP FUNCTION GetStudentAge GO CREAT ...

  6. CMD直接输入Java,Javac,Javap发生乱码解决方式

    首先需要设置jdk的默认编码,在之前一篇博文里有 然后在cmd里直接执行chcp 65001   代表将cmd换成UTF-8的显示页 936是GBK 437为英语

  7. cad转换成png,svg

    1.设置仓库可以在setting.xml中设置(也可以在pom中设置,设置项即可) <mirror> <id>AsposeJavaAPI</id> <name ...

  8. WPF 饼状图,柱形图,折线图 (3 饼状图)

    网址:https://www.cnblogs.com/CSSZBB/p/12746214.html 饼状图相对来说复杂一些.因为需要计算很多坐标,线来看下这个列子. 圆首先想到Ellipse.但是El ...

  9. Spring详解(九)------事务管理

    1.事务介绍 事务(Transaction),一般是指要做的或所做的事情.在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit). 这里我们以取钱的例子来讲解:比如你去ATM ...

  10. Thread类的常用方法----多线程基础练习

    创建多线程程序的第一种方式----继承Thread类 常用API 构造方法 public Thread() :分配一个新的线程对象. public Thread(String name) :分配一个指 ...