Какой смысл того, чтобы иметь $this и сам:: в PHP?

Почему 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?

19
задан NullUserException 30 July 2010 в 23:07
поделиться

4 ответа

Хорошо, давайте избавимся от необходимости писать везде $ this . Взгляните на эту ситуацию:

class Foo {
    public function setBar($value) {
        $bar = $value;
    }
}
$foo = new Foo();
$foo->setBar('some value');

Является ли $ bar локальной переменной или членом $ foo ?

Должно быть какое-то различие. Они могли бы разрешить объявление локальных переменных с помощью ключевого слова var , но это не имело бы обратной совместимости и было бы очень запутанным для людей, обновляющихся с более старых версий PHP.

То же самое применимо к self :: . Как интерпретатор узнает, является ли функция, которую вы хотите вызвать, глобальной или специфической для класса?

14
ответ дан 30 November 2019 в 03:38
поделиться

PHP не был ООП.

Теперь это так, но с побочными эффектами.

6
ответ дан 30 November 2019 в 03:38
поделиться

Поскольку это было повторно открыто, я опубликую здесь свой ответ , как и обещал.

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;

В PHP определенные локальные переменные определяются во время выполнения

Переменные не нужно объявлять; следовательно, в зависимости от пути кода в какой-то момент переменная может быть определена или не определена. Чтобы добавить оскорбления к травме, у нас также есть монстр под названием «переменные переменные». Пример:

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 данный идентификатор может также представлять внутри одной и той же функции локальную переменную и свойство, но:

  • Не в одном блоке (в PHP все блоки в функции имеют одинаковые сфера).
  • Вы получаете предупреждение, если скрываете собственность.
  • Важно отметить, что в любом данном появлении идентификатора это либо свойство, либо локальная переменная , иногда это не может быть одно, а иногда другое.

Последствия

Из-за этих фактов было бы невозможно определить во время компиляции, относится ли $ var к локальной переменной или к свойству. Следовательно:

  • Во время выполнения каждый раз, когда возникает переменная, она должна сначала искать в локальной таблице символов, затем в таблице свойств экземпляра и, наконец, в списке статических свойств или в любом другом порядке (поскольку там может Это не экземпляр, и необходимо объявить статическое свойство с тем же именем и статическими свойствами, здесь может быть некоторый потенциал оптимизации, но суть остается. Это означает, что в худшем случае символ придется искать в трех разных местах. Это плохо с точки зрения производительности.
  • Один и тот же символ может означать разные вещи в разных случаях. Это рецепт катастрофы.
15
ответ дан 30 November 2019 в 03:38
поделиться

На самом деле, я знаю людей, которые этим пользуются. в Java, даже там, где это не нужно, потому что они считают, что это создает более ясный код;) У меня нет действительно определенного ответа, но я предполагаю, что внутренне получение $ var всегда должно быть преобразовано в $ this-> var. Так что это не значит, что кто-то намеренно усложняет ситуацию, заставляя нас использовать $ this-> var, а просто решил не реализовывать ярлык $ var. Если это хоть как-то поможет, я не знаю;)

1
ответ дан 30 November 2019 в 03:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: