Почему PHP требует, чтобы Вы явно записали $this
? Я понял бы, необходимо ли было использовать $this
здесь:
function foo($bar) {
$this->bar = $bar;
}
Но необходимо записать это явно в подробном коде, который похож на это:
$this->var3 = globalFun($this->var, $this->var2[$this->anotherVar], $this->method());
в противоположность:
$var3 = globaFun($var, $var2[$anotherVar], method());
Таким образом какой смысл $this
?
Почему мы должны дифференцировать статические ссылки и экземпляры? Почему делают нам нужно:
static function getValue() {
return self::value;
}
Не может PHP узнавать во времени выполнения, если рассматриваемая переменная/метод статична? Теперь, если я хочу изменить метод от статического до непомех, я должен заменить все они self::
с $this->
(и наоборот).
Не был бы это быть лучше, если у нас был a $this
это ведет себя как он, делает в Java?
Хорошо, давайте избавимся от необходимости писать везде $ this
. Взгляните на эту ситуацию:
class Foo {
public function setBar($value) {
$bar = $value;
}
}
$foo = new Foo();
$foo->setBar('some value');
Является ли $ bar
локальной переменной или членом $ foo
?
Должно быть какое-то различие. Они могли бы разрешить объявление локальных переменных с помощью ключевого слова var
, но это не имело бы обратной совместимости и было бы очень запутанным для людей, обновляющихся с более старых версий PHP.
То же самое применимо к self ::
. Как интерпретатор узнает, является ли функция, которую вы хотите вызвать, глобальной или специфической для класса?
PHP не был ООП.
Теперь это так, но с побочными эффектами.
Поскольку это было повторно открыто, я опубликую здесь свой ответ , как и обещал.
TL; версия DR Если бы не требовалось квалифицировать доступ к члену, были бы не только штрафы за производительность, но и одна и та же строка кода могла бы одновременно обозначать доступ к полю и доступ к локальной переменной, в зависимости от кодовый путь.
В PHP за столом всегда активна одна таблица символов. Это либо глобальная таблица символов, либо локальная таблица символов функции / метода (которые, кстати, строятся лениво). Помимо суперглобальных переменных и таких оптимизаций, как скомпилированные переменные, когда запрашивается переменная $ var
, она ищется в текущей таблице символов. Поскольку свойства объекта находятся не в таблицах символов, а в объектах (свойства экземпляра) или в структуре, связанной с классом (статические свойства), поиск для $ var
никогда не может вернуть имущество.
Чтобы добавить заданную переменную в область видимости функции, вы должны явно обозначить свое намерение, создав ссылку. Примеры:
$myglobal = 7;
class A {
private $prop;
public function meth() {
global $myglobal; //bring a global to the current scope
$prop =& $this->prop; //brings a property to the current scope
$local = 4;
$lambda = function () use (&$local) { };
}
}
Очевидно, это просто более изощренный способ сформулировать то, что происходит в настоящее время. Возникает вопрос , почему такое поведение?
В конце концов, в Java нам нужно набирать this.prop
только тогда, когда есть локальная переменная с именем prop
, скрывающая свойство. Почему это не лучший вариант для PHP?
Я могу придумать несколько причин.
В PHP есть нечто, называемое «динамическими свойствами». Вы можете назначать новые свойства объектам во время выполнения.Фактически, учитывая два объекта одного и того же класса, один может иметь заданное свойство $ a
, а другой - нет. Пример:
$obj1 = new stdClass();
$obj2 = new stdClass();
$obj1->a = 7;
Переменные не нужно объявлять; следовательно, в зависимости от пути кода в какой-то момент переменная может быть определена или не определена. Чтобы добавить оскорбления к травме, у нас также есть монстр под названием «переменные переменные». Пример:
class A {
private $g = 3;
public function func($varname) {
if (rand(1,2) == 1) {
$g = 4; //no block scope; the scope is the function's
}
$$varname = 5; //god knows what's happening here
//if local variables hid properties, we'd have trouble
}
}
В Java данный идентификатор может также представлять внутри одной и той же функции локальную переменную и свойство, но:
Из-за этих фактов было бы невозможно определить во время компиляции, относится ли $ var
к локальной переменной или к свойству. Следовательно:
На самом деле, я знаю людей, которые этим пользуются. в Java, даже там, где это не нужно, потому что они считают, что это создает более ясный код;) У меня нет действительно определенного ответа, но я предполагаю, что внутренне получение $ var всегда должно быть преобразовано в $ this-> var. Так что это не значит, что кто-то намеренно усложняет ситуацию, заставляя нас использовать $ this-> var, а просто решил не реализовывать ярлык $ var. Если это хоть как-то поможет, я не знаю;)