首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >理解PHP的延迟静态绑定

理解PHP的延迟静态绑定

作者头像
zlmai
发布2018-09-24 13:30:21
发布2018-09-24 13:30:21
1.6K0
举报
文章被收录于专栏:zlmai的专栏zlmai的专栏

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

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

转发调用

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

非转发调用

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

后期静态绑定原理

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

例子1,简单使用static::

代码语言:javascript
复制
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();

输出:

代码语言:javascript
复制
B

分析:运行B::test()会调用B中继承自A的test方法,然后会执行static::who(),而static::中的static表示运行时所在类的别名,此时运行的类名是B,所以static::who()就是执行B中的who方法,所以输出B。

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

代码语言:javascript
复制
class A {
    public static function foo() {
        static::who();
    }

    public static function who() {
        echo __CLASS__."\n";
    }
}

class B extends A {
    public static function test() {
        A::foo();
        parent::foo();
        self::foo();
    }

    public static function who() {
        echo __CLASS__."\n";
    }
}
class C extends B {
    public static function who() {
        echo __CLASS__."\n";
    }
}

C::test();

输出:

代码语言:javascript
复制
A
C
C

分析:运行C::test()会调用C继承自B的test方法,这个方法中首先执行的是A中的foo方法,此时属于静态方法调用,static对应的类名就是明确指定的那个A类,故会输出A;然后是parent::foo()和self::foo()方法,这两个都属于转发调用,前一个调用的是B的foo方法,后一个调用的是C的foo方法,实际的执行内容都是static::foo(),当static::中的static其实是运行时所在类的别名,此时运行的类是C,所以都会输出C。

例子3,使用场景举例

代码语言:javascript
复制
class Model 
{ 
    public static function find() 
    { 
        echo static::$name; 
    } 
} 

class Product extends Model 
{ 
    protected static $name = 'Product'; 
} 

Product::find(); 

输出:

代码语言:javascript
复制
Product

分析:Product::find()方法运行的是Product继承自Model的find方法,这个方法中的static对应于此时正在执行的类名,即Product,所以相当于运行Product:: $name,输出了Product。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 转发调用
  • 非转发调用
  • 后期静态绑定原理
  • 例子1,简单使用static::
  • 例子2,区分转发调用和非转发调用
  • 例子3,使用场景举例
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档