搜索
首页php教程php手册1.2魔术方法和延迟静态绑定

一.魔术方法:

  1.__get,__set

  __get:获取一个不可访问的属性时触发(不可访问指属性不存在,或者没有访问权限)

  __set:为一个不可访问的属性赋值的时候触发

  2.__isset,__unset

  __isset:当用isset()函数判断一个不可访问的属性时触发

  __unset:当用unset()函数操作一个不可访问的属性时触发

  3.__call,__callStatic

  __call:当调用一个不可访问的方法时触发

  __callStatic:当调用一个不可访问的静态方法时触发

  4.__construct,__destruct

  __construct:初始化一个对象时触发

  __destruct:对象销毁,或者脚本执行完时触发

  5.__autoload

  __autoload:当使用一个不可访问的类时触发

  6.__clone

  __clone:对象被克隆时触发

  7.__sleep,__wakeup

  __sleep:使用serialize时触发

  __wakeup:使用unserialize时触发

  8.__toString,__invoke

  __toString:当一个对象被当做字符串来操作时触发,如$obj是一个对象,echo $obj,就会触发__toString

  __invoke:当一个对象被当做函数来使用时触发,如$obj是一个对象,$obj()就会触发__invoke

 

二.延迟静态绑定

  抛开概念看例子理解就好:

  首先延迟静态绑定是怎么出现的?看下面例子:

class A{<br>}<br>class B extends A{<br>    public static function out(){<br>        return new self();<br>    }<br>}<br>class C extends A{<br>    public static function out(){<br>        return new self();<br>    }<br>}<br>var_dump(B::out());//结果是object(B)#1 (0) { }<br>var_dump(C::out());//结果是object(C)#1 (0) { }<br>然后我们将子类中相同的代码抽取到父类class A中,变成:
class A{<br>    public static function out(){<br>        return new self();<br>    }<br>}<br>class B extends A{<br>}<br>class C extends A{<br>}<br>var_dump(B::out());//结果是object(A)#1 (0) { }<br>var_dump(C::out());//结果是object(A)#1 (0) { }<br>这个结果显然不是我们想要的,这里的问题主要是因为self指代的是它所在的类.这里self在类A里面,所以返回的永远是类A的对象,<br>而我们想要的是让out()方法返回调用它的类的对象而不是它所在的类的对象.怎么办?<br>此时我们马上可以想到$this可以代表调用它的对象,但是out()是一个静态方法,里面是不能出现$this的,怎么办?<br>用static.它也代表调用它的对象如:
class A{<br>    public static function out(){<br>        return new static();<br>    }<br>}<br>class B extends A{<br>}<br>class C extends A{<br>}<br>var_dump(B::out());//结果是object(B)#1 (0) { }<br>var_dump(C::out());//结果是object(C)#1 (0) { }<br>这样就好了.这就是延迟静态绑定.<br><br>在看下面的例子:

为什么是这个结果呢?我们分析一下:

首先对象c调用get()方法,但是在类C中没有找到,于是它去类B中找,找到了.然后执行这个get方法,

先执行A::foo(); 类A会直接调用它自己的foo(),输出`fooA`,然后调用out,很明显这里调用static::out()的就是类A,所以输出的类名也是A.(这里侧重于类A)

再执行parent::foo(); parent表示父类,这里会去执行类A中的foo(),输出`fooA`,然后执行static::out(),此时调用这个static的不是类A,而是类C,因为parent代表的是父类,但不代表具体哪一个类(这里侧重于父类中的方法,而不管父类是谁).

然后执行self::foo(); self表示它所在的类(类B),它先执行foo(),没有再去父类中找,所以输出`fooA`,然后执行static::out(),同理这里使用static的不是类A,而是类C,self虽然代表类B,但是self不能代表一个具体的类.

简单点说:对象c开始执行get()-->A::foo();此时链子就断了,变成由类A直接去调用foo()了,和对象c没关系了.这里的static当然指的是类A.

     接着,对象c-->parent::foo()-->类A中的foo()-->static::out(),这里的parent说白了就是一个指向作用,即执行谁的foo()方法.所以可以理解为对象c调用类A中的foo方法.那么foo中的static代表类C

     最后,对象c-->self::foo()-->类A中的foo()-->static::out(),同上,这里的self也是一个指向的作用,但是最终还是到了类A.可以理解为对象c调用类A中的foo方法.那么foo中的static代表类C

 


<br><br>
声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

功能强大的PHP集成开发环境