细说PHP后期静态绑定

概念

后期静态绑定这个概念平时听的很少,但是在项目中使用却相当广泛,理解了它,日常面向对象开发时将会非常顺手,关于PHP后期静态绑定,官方文档有相关的解释:

准确说,后期静态绑定工作原理是存储了在上一个“非转发调用”(non-forwarding call)的类名。当进行静态方法调用时,该类名即为明确指定的那个(通常在 :: 运算符左侧部分);当进行非静态方法调用时,即为该对象所属的类。所谓的“转发调用”(forwarding call)指的是通过以下几种方式进行的静态调用:self::,parent::,static:: 以及 forward_static_call()。可用 get_called_class() 函数来得到被调用的方法所在的类名,static:: 则指出了其范围。

该功能从语言内部角度考虑被命名为“后期静态绑定”。“后期绑定”的意思是说,static:: 不再被解析为定义当前方法所在的类,而是在实际运行时计算的。也可以称之为“静态绑定”,因为它可以用于(但不限于)静态方法的调用。

说的很抽象,地球人很难理解...

举个栗子

让我们先看一段代码:

class Model
{
    public static function query()
    {
        echo "query table " . self::table() . "\n";
    }

    public static abstract function table();
}

class UserModel extends Model
{
    public static function table()
    {
        return 'user';
    }
}

UserModel::query();

父类Model定义了一个query方法,以及一个获取表名的table抽象方法,我们希望继承它的子类来实现这个方法,定义自己的table名称,并且都能通过query方法来获取自己的table,其中调用table方法使用了self关键字,我们看看这段代码会返回什么:

Fatal error: Uncaught Error: Cannot call abstract method Model::table()

代码直接报错了,并没有如愿调用UserModeltable方法,而是直接调用了父类的抽象方法。

非转发调用转发调用

  • 非转发调用指的是明确指定了类名的静态调用,比如Foo::bar()

  • 转发调用指的是通过self::,parent::,static::,forward_static_call()这些没有明确指定类名的静态调用,以上代码调用table方法就是转发调用。

后期静态绑定

以上代码我们希望子类调用query时能够自动调用自己的table类来获取表名,很明显这里是不能直接使用非转发调用的,因为父类并不知道继承他的子类叫什么,为了实现这个逻辑,PHP引入了后期静态绑定这个功能,并且使用了转发调用的关键字static来描述这个调用。

下面我们来重写父类的query方法,将self改成static

class Model
{
    public static function query()
    {
        echo "query table " . static::table() . "\n";
    }

    public static abstract function table();
}

再次调用UserModel::query(),得到了我们想要的返回:

query table user

再举一个例子,最常用的单例模式,在父类中封装一个实例化对象的方法我们可以直接使用new static()来实现:

abstract class Factory
{
    public static $instance = null;

    public static function getInstance()
    {
        if (is_null(self::$instance)) {
            self::$instance = new static();
        }

        return self::$instance;
    }
}
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇