Подтвердить что ты не робот

Вызов PHP-родительских конструкторов со старым/новым синтаксисом

Учитывая класс Foo с конструктором старого стиля

class Foo
{
    public function Foo()
    {
        //does constructing stuff
    }
}

Есть ли какая-либо функциональная разница между вызовом родительского конструктора с новым конструктором стиля или конструктором старого стиля?

class Bar extends Foo
{
    public function Bar()
    {
        //does it matter?
        //parent::__construct();
        //parent::Foo();
    }
}

Иными словами, есть ли что-то особенное в статическом вызове

parent::__construct()

когда он сделан из конструктора, или это просто стандартный статический вызов?

Перед лучшими практиками Летающие обезьяны спускаются, я имею дело с некоторым устаревшим кодом и пытаюсь понять последствия всего происходящего.

4b9b3361

Ответ 1

Я бы сказал, что оба синтаксиса делают точно то же самое...
Edit: после написания остальной части ответа, на самом деле, это не совсем верно ^^ Это зависит от того, что вы заявляете; см. два примера:


Если вы определяете Foo как конструктор и вызываете его с помощью __construct, кажется, что он работает; следующий код:

class Foo {
    public function Foo() {
        var_dump('blah');
    }
}

class Bar extends Foo {
    public function Bar() {
        parent::__construct();
    }
}

$a = new Bar();

Выходы

string 'blah' (length=4)

Итак, теперь все ОК, -)


С другой стороны, если вы определяете __construct и вызываете Foo, вот так:

class Foo {
    public function __construct() {
        var_dump('blah');
    }
}

class Bar extends Foo {
    public function Bar() {
        parent::Foo();
    }
}

$a = new Bar();

Это приведет к фатальной ошибке:

Fatal error: Call to undefined method Foo::foo()

Итак, если ваш класс объявлен с помощью старого синтаксиса, вы можете назвать его в обоих направлениях; и если он определен с помощью нового (PHP5) синтаксиса, вы должны использовать этот новый синтаксис - что имеет смысл, afterall: -)


BTW, если вы хотите какое-то "реальное доказательство", вы можете попробовать использовать Vulcan Logic Disassembler, который даст вам коды операций, соответствующие PHP script.


ИЗМЕНИТЬ после комментария

Я загрузил результаты использования VLD с обоими синтаксисами:  - vld-construct-new.txt: при объявлении __construct и вызове __construct.  - vld-construct-old.txt: при объявлении Foo и вызове __construct.

Выполняя разницу между двумя файлами, я получаю:

$ diff vld-construct-old.txt vld-construct-new.txt
25c25
< Function foo:
---
> Function __construct:
29c29
< function name:  Foo
---
> function name:  __construct
44c44
< End of function foo.
---
> End of function __construct.
71c71
< Function foo:
---
> Function __construct:
75c75
< function name:  Foo
---
> function name:  __construct
90c90
< End of function foo.
---
> End of function __construct.

(Унифицированный diff намного длиннее, поэтому я буду использовать формат "diff" по умолчанию здесь)

Таким образом, единственные различия в дизассемблированных кодах операций - это имена функций; как в классе Foo, так и в классе Bar (который наследует метод __construct/Foo класса Foo).

Я бы сказал, что:

  • Если вы пишете код PHP 5 (и в 2009 году я искренне надеюсь, что вы сделаете ^^), тогда просто используйте синтаксис __construct
  • Вам нужно сохранить старый код PHP 4, который вы не можете перенести на PHP 5 (вам нужно), затем используйте синтаксис Foo...


В качестве ссылки, в документации говорится (цитирование):

Для обратной совместимости, если PHP 5 не может найти функцию __construct()для данного класса он будет искать функция конструктора старого стиля, имя класса.

Эффективно это означает, что единственное случай, который имел бы совместимость проблема заключается в том, что класс имел метод названный __construct(), который использовался для различной семантики.

Итак, я действительно думаю, что не так много различий : -)


Вы столкнулись с какой-то странной проблемой, которую, по вашему мнению, вызвано чем-то вроде разницы между двумя синтаксисами?