10
<?php
class Record {

    protected static $tableName = 'base';

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

它显示:基础

问题:

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

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

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

4

4 回答 4

29

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

使用self,它是在编译时决定的(当代码被“读取”时),它self指的是Record. 稍后User解析 for 的代码,但self::$tableNameinRecord已经引用Record::$tableName并且不能再更改。

使用static时,引用不会立即解析。它仅在您调用时才被解析User::getTableName(),此时您处于 的上下文中User,因此static::$tableName被解析为User::$tableName

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

于 2013-07-22T08:01:42.087 回答
4

self引用定义类范围。

static引用调用类范围。

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

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

于 2013-07-22T08:05:34.527 回答
2

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

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()从since输出的$name变量是根据您在其中定义的绝对当前类计算得出的。要解决这种情况,请使用.Aselfselfstatic

于 2014-09-05T13:17:41.877 回答
-1

建议您阅读“对象继承” http://www.php.net/manual/en/language.oop5.inheritance.php

于 2013-07-22T07:59:47.960 回答