Пытаясь понять поздние статические привязки в 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;
, она называется "поздними статическими привязками", я прочитал документ здесь, но все еще не совсем понял. Не могли бы вы дать мне несколько объяснений:
а. почему эта строка кода echo self::$tableName;
показывает: base?
б. почему эта строка кода echo static::$tableName;
показывает: пользователи?
Ответы
Ответ 1
self
"привязан" во время компиляции статически. Это означает, что при компиляции кода определяется, к чему относится self
. static
разрешается во время выполнения, то есть когда код выполняется. Это позднее статическое связывание. И это различие.
С self
, это определяется во время компиляции (когда код "читается" ), что self
относится к Record
. Позже код для User
анализируется, но self::$tableName
в Record
уже ссылается на Record::$tableName
и больше не может быть изменен.
Когда вы используете static
, ссылка не будет устранена немедленно. Он разрешается только при вызове User::getTableName()
, после чего вы находитесь в контексте User
, поэтому static::$tableName
разрешено User::$tableName
.
Другими словами: self
всегда относится к классу, в котором он был написан, и не имеет двух способов. То, к чему относится static
, зависит от того, какой контекст он использовал; на практике это означает, что он может ссылаться на дочерние классы, если класс, в котором он встречается, расширяется. Это заставляет его работать как $this
, только для статических контекстов.
Ответ 2
self
ссылается на область определения класса.
static
ссылается на область вызовов классов.
self::$tableName
ссылается на класс, в котором он был определен. т.е. Запись
static::$tableName
ссылается на класс, на который он был вызван. т.е. Пользователь
Ответ 3
Пример ниже даст минимальный пример позднего статического привязки:
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
из A
, так как self
вычисляется из класса абсолютного тока, который вы определили self
in. Чтобы решить такие случаи, используйте static
.
Ответ 4
предложите вам прочитать о "Наследование объектов" http://www.php.net/manual/en/language.oop5.inheritance.php