PHP后期静态绑定的(late static bindings)

理解PHP延迟静态绑定

static::中的static其实是运行时所在类的别名,并不是定义类时所在的那个类名。这个东西可以实现在父类中能够调用子类的方法和属性。

使用(static)关键字来表示这个别名,和静态方法,静态类没有半毛钱的关系,static::不仅支持静态类,还支持对象(动态类)。

转发调用:

所谓的“转发调用”(forwarding call)指的是通过以下几种方式进行的静态调用,self::,parent::,static::以及forward_static_call()。

非转发调用

那么非转发调用其实就是明确指定类名的静态调用(foo::bar())和非静态调用($foo->bar())

后期静态绑定原理

后期静态绑定工作原理是存储了在上一个“非转发调用”(non-forwarding call)的类名。

例子1,简单实用static

class A

{

public static function who()

{

echo CLASS;

}

public static function test()
{
static::who();// 后期静态绑定从这里开始
}

}

class B extends A{

public static function who()

{

echo CLASS;

}

}

B::test();

以上程序会输出:

B

例子2,区分转发和非转发调用

class A

{

public static function foo()

{

static::who();

}

public static function who()
{
echo __CLASS__;
}

}

class B extends A

{

public static function test()

{

A::foo();

parent::foo();

self::foo();

}

public static function who()
{
echo __CLASS__;
}

}

class C extends B

{

public static function who()

{

echo CLASS;

}

}

C::test();

以上程序会输出:

A C C

在这里主要分析下例子2。

1、C::test(),这是一个非转发调用,因为::前面有类名C。

2、进入test()方法,有三个静态调用A::foo(),parent::foo(),self::foo(),对于这三个静态调用来说,它们的非转发调用类就是C。

3、现在执行A::foo(),这是一个非转发调用。A::foo()中的代码是static::who(),这是一个转发调用,对于这个转发调用来说他的非转发调用类就是不再

是C而是A(因为之前执行了A::foo())。因此执行的结果为A。

4、现在执行parent::foo(),这是一个转发调用,转发到哪里呢?就是它的上一个非转发调用的类,也就是C

(在步骤2中提到的)。在这里一定要注意虽然在这之前执行了A::foo(),但是parent::foo()的上一个非转发调用的类任然是类C,

因此执行的结果是C。

5、现在执行self::foo(),这个和parent::foo()一样都是转发调用,因此也输出C。

使用后期静态绑定的好处

后期静态绑定目前我看到家多的是用于对象实例化中,在实例化对象时,static会根据运行时调用的类来决定实例化对象,

而self则是分局所在位置的类来决定实例化对象。当我们只想实例化子类,并且不希望后续再对子类的使用中由于父类的变化对

子类产生了影响时,后期静态绑定就能发挥它的作用了。

PHP之后期静态绑定的更多相关文章

  1. PHP的后期静态绑定

    self 是个孝子 不管后来 谁是它的领导(调用它)  谁生了它  它就听谁的 子类调用父类的方法 self 的生存空间是父类 不管是不是子类调用 我生在哪 我就在哪个类里面找属性/方法 static ...

  2. php中的后期静态绑定

    后期静态绑定PHP手册 使用的保留关键字: static 定义: static:: 不再被解析为定义当前方法所在的类,而是在实际运行时计算的.也可以称之为"静态绑定",因为它可以用 ...

  3. php后期静态绑定

    php后期静态绑定 自 PHP 5.3.0 起,PHP 增加了一个叫做后期静态绑定的功能,用于在继承范围内引用静态调用的类. 虽然也可以调用非静态方法,但是不会在运行时绑定. static 不再只是简 ...

  4. static后期静态绑定

    先说一下__CLASS__,get_class() ,  get_called_class() 区别: __CLASS__获取当前的类名, get_class()与上面一样,都是获取当前的类名, ge ...

  5. 139-PHP static后期静态绑定(二)

    <?php class test{ //创建test类 public function __construct(){ static::getinfo(); //后期静态绑定 } public s ...

  6. 138-PHP static后期静态绑定(一)

    <?php class test{ //创建test类 public function __construct(){ self::getinfo(); //后期静态绑定 } public sta ...

  7. php中的后期静态绑定("Late Static Binding")

    在我们以往中,在类中使用self关键字的时候都是指向了被调用方法定义时的类,而非原始的调用类. 例如: class Animal{ static $IQ_lv_avg = 1; public stat ...

  8. 父类方法返回子类实例:PHP延迟静态绑定

    案例分析 先前的PHP项目中,看到类似于以下的一段代码: <?php class DBHandler { public function get() { } } class MySQLHandl ...

  9. 静态绑定 self 和 static的区别

    后期静态绑定 自 PHP 5.3.0 起,PHP 增加了一个叫做后期静态绑定的功能,用于在继承范围内引用静态调用的类. 准确说,后期静态绑定工作原理是存储了在上一个“非转发调用”(non-forwar ...

随机推荐

  1. HashMap中的hash算法总结

    前言 算法一直是我的弱项,然而面试中基本是必考的项目,刚好上次看到一个HashMap的面试题,今天也来学习下 HashMap中的hash算法是如何实现的. 数学知识回顾 << : 左移运算 ...

  2. 入门:移动APP中的各种导航

    即使是移动应用界面的原型设计,导航的形式也可以多种多样.尽管尺寸小,又必须紧凑排列大量数据,它们似乎受到了紧密的约束,但依然有着形形色色的选择. 人们曾经一度只会考虑一种形式——流行且广泛使用的垂直导 ...

  3. 每日英语:Dashing the China Dream

    Much has been said about what the 'China Dream' really means to many Chinese -- whether it is nation ...

  4. JUnit+Mockito结合测试Spring MVC Controller

    [本文出自天外归云的博客园] 概要简述 利用JUnit结合Mockito,再加上spingframework自带的一些方法,就可以组合起来对Spring MVC中的Controller层进行测试. 在 ...

  5. MySQL中文参考手册

    1 MySQL 的一般信息 这是MySQL参考手册:它记载了MySQL版本3.23.7-alpha. MySQL 是一个快速.多线程.多用户和强壮的SQL数据库服务器. 对Unix和 OS/2 平台, ...

  6. Go Revel - Testing(测试模块)

    revel提供了一个测试框架来方便的为自己的程序编写功能测试用例. 默认创建的应用骨架附带一个简单的测试用例,这里将它作为起点 ##概览 测试保存在`tests`目录: corp/myapp app/ ...

  7. Java知多少(24)包装类、拆箱和装箱详解

    虽然 Java 语言是典型的面向对象编程语言,但其中的八种基本数据类型并不支持面向对象编程,基本类型的数据不具备“对象”的特性——不携带属性.没有方法可调用. 沿用它们只是为了迎合人类根深蒂固的习惯, ...

  8. 关于Unity的两种调试方法

    Unity的两种调试方法 1.Debug.Log()输出语句调试,平时经常用这个 2.把MonoDevelop和Unity进行连接后断点调试 先把编辑器选择为MonoDevelop,Edit----& ...

  9. vector、map 内存释放

    一.vector void TestVector() { cout << "begin create vector" << endl; int iSize ...

  10. Thinkphp5 关联模型

    必须建立两个模型分类模型(attr).文章模型(article) attr模型 <?php namespace app\common\model; use think\Model; class ...