Почему 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->
(и наоборот).
Не было бы лучше, если бы у нас было такое $this
которое ведет себя так же, как на Java?
Хорошо, давайте удалим необходимость писать $this
всюду. Взгляните на эту ситуацию:
class Foo { public function setBar($value) { $bar = $value; } } $foo = new Foo(); $foo->setBar('some value');
Является ли $bar
локальной переменной или членом $foo
?
Должна быть какая-то дифференциация. Они могли бы разрешить объявление локальных переменных с ключевым словом var
, но это не было бы обратной совместимостью и было бы очень запутанным для людей, обновляющих старые версии PHP.
То же самое относится и к self::
Как интерпретатор знает, является ли функция, которую вы хотите вызвать, глобальной или конкретной для класса?
Поскольку это было вновь открыто, я отправлю здесь свой ответ , как и обещал.
Версия 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
ссылается на локальную переменную или на свойство. Вследствие этого:
PHP не был ООП.
Теперь это, но с побочными эффектами.
На самом деле, я знаю людей, которые используют это. в Java даже там, где это не нужно, потому что они считают, что он создает более четкий код;) У меня нет определенного ответа, но я полагаю, что внутренне получение $ var всегда должно быть переведено в $ this-> var. Поэтому не похоже, что кто-то намеренно усложнил ситуацию, заставив нас делать $ this-> var, но просто решил не реализовывать ярлык $ var. Если это помогает, я не знаю;)