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

在看下面的例子:

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

首先对象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


				
时间: 2024-08-04 01:57:17

1.2魔术方法和延迟静态绑定的相关文章

数据持久化、单例、重载【添加对不可访问的成员的操作】、魔术方法、类常量、static关键字对self的补充【静态延迟绑定实现$this的效果】、参数类型约束【参数前加类名】、遍历【iterator接口】、快速排序

1.数据持久化过程[传输(例如表单提交或php交互mysql)和保存过程] 使用的是字符串形式的流数据. 数据流就是为了传输[按照序列的形式进行传输] [http://baike.baidu.com/link?url=0MtUQMhFzc_EwJc09rXZV8KlfOL4jis6XNbRfmGA3rQhDcGwOp8togLVQjXBV34M] 所以将其他类型数据转化为字符串的过程也是序列化的过程 [这个概念和图片.视频的流媒体的区别?] [注意点] 另外mysql中sql语句中的某些关键词为

PHP延迟静态绑定:static关键字

PHP5.3中引入了延迟静态绑定的概念.该特性最明显的标志就是新关键字static.static类似于self,但它指的是被调用的类而不是包含类.在本例中,它的意思是调用Document::create()将生成一个新的Document对象,而不是试图实例化一个DomainObject对象. 因此,现在在静态上下文中使用继承关系. abstract class DomainObject{ public static function create(){ return new static();

PHP Static延迟静态绑定

初识PHP Static延迟静态绑定 PHP5.3以后引入了延迟静态绑定static,它是为了解决什么问题呢?php的继承模型中有一个存在已久的问题,那就是在父类中引用扩展类的最终状态比较困难.来看一个例子. PHP 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class A { public static function echoClass(){ echo __CLASS__; } public static function tes

PHP延迟静态绑定 static关键字

示例代码1 abstract class Parent { } class Man extends Parent { public static function create(){ return new Man(); } } class Woman extends Parent { public static function create(){ return new Woman(); } } 示例代码有一个parent父类,还包含Man和Woman两个子类,并在该两个类中都包含创建本身的的静

“延迟静态绑定”的使用

Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--> 1 <?php class ParentBase { static $property = 'Parent Value'; public static function render() { return self::$property; } } class Descendant extends P

延迟静态绑定

延迟静态绑定 PHP的继承模型中有个存在已久的问题,那就是在父类中引用扩展类的最终状态比较困难. class ParentBase{ static $property = 'Parent Value'; public static function render(){ return self::$property; } } class Descendant extends ParentBase{ static $property = 'Descendant Value'; } echo Desc

PHP延迟静态绑定(本文属于转发)

这段时间看项目后台的PHP代码,看到了类似于以下的一段代码,我把它抽出来: <?php class DBHandler { function get() {} } class MySQLHandler extends DBHandler { // 这里一个create public static function create() { echo "MySQL"; return new self(); } public function get() { echo "MyS

PHP延迟静态绑定

php5.3已经开始支持延迟静态绑定. 延迟静态绑定指的是在父类中获取子类的最终状态.在父类中,如果出现self关键字,被子类继承后,这个self值的还是父类而不是子类. 如果在父类中出现了self关键字,并且子类继承了含有self的这段代码,那么需要考虑静态延迟绑定.在父类中使用static代替self 如下例: <?php class A{ public static $a=1; public function test(){ echo self::$a;//自身的属性a } } class

PHP &quot;延迟静态绑定&quot; 功能,static

从这个名字的定义提取出两个关键点,第一点静态,也就是说这个功能只适用于静态属性或静态方法.第二点延迟绑定,这个根据下面代码就可以很好的理解 看一下这个例子: class A{ static $name = "Tom"; public function printName(){ echo self::$name."\n"; self::fun(); } static function fun(){ echo "A Class\n"; } } cla