<?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;
显示:用户?
答案 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)