试图理解PHP中的后期静态绑定

时间:2013-07-22 07:52:33

标签: php

<?php
class Record {

    protected static $tableName = 'base';

    public static function getTableName() {
        echo self::$tableName;
    }
}
class User extends Record {
    protected static $tableName = 'users';
}
User::getTableName(); 

它显示:base

问题:

我知道我可以通过将此行echo self::$tableName;更改为echo static::$tableName;来更改此问题,它被称为“后期静态绑定”,我阅读了文档here,但仍然不太了解它。那你可以给我一些解释:

一个。为什么这行代码echo self::$tableName;显示:base?

湾为什么这行代码echo static::$tableName;显示:用户?

4 个答案:

答案 0 :(得分:29)

self在编译时是静态的“绑定”。这意味着当代码编译时,决定self引用的是什么。 {em>运行时解析static,即代码执行时。那是静态绑定。这就是区别。

使用self,在编译时决定(当代码为“已读”时),self引用Record。稍后会解析User的代码,但self::$tableName中的Record已引用Record::$tableName且无法再更改。

使用static时,不会立即解析引用。只有在您致电User::getTableName()时才会解决此问题,此时您处于User的上下文中,因此static::$tableName已解析为User::$tableName

换句话说:self总是引用它所写的类,没有两种方式。 static所指的内容取决于它所使用的上下文;在实践中,这意味着它可以引用子类,如果它正在扩展的类。这使它像$this一样工作,仅适用于静态上下文。

答案 1 :(得分:4)

self引用了定义的类范围。

static引用调用类范围。

self::$tableName引用定义它的类。即记录

static::$tableName引用它所调用的类。即用户

答案 2 :(得分:1)

以下示例将给出后期静态绑定的最小示例:

class A {
    static public $name = "A";

    static public function getName () {
        return self::$name;
    }

    static public function getNameLateStaticBinding () {
        return static::$name;
    }
}


class B extends A {
    static public $name = "B";
}



// Output: A
echo A::getName(), "\n";

// Output: A
echo B::getName(), "\n";

// Output: B
echo B::getNameLateStaticBinding() , "\n";

B::getName()输出$name的{​​{1}}变量,因为A是根据您定义的绝对当前类self计算的。要解决此类情况,请使用self

答案 3 :(得分:-1)