Учитывая класс 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()
когда он сделан из конструктора, или это просто стандартный статический вызов?
Перед тем, как лучше всего подойдут Летающие обезьяны, я имею дело с некоторым устаревшим кодом и пытаюсь понять последствия всего происходящего.
Я бы сказал, что оба синтаксиса делают точно то же самое …
Изменить: после написания остальной части ответа, на самом деле, это не совсем так. ^^ Это зависит от того, что вы заявляете; см. два примера:
Если вы определяете 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-скрипту.
EDIT после комментария
Я загрузил выходы с использованием 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 не может найти функцию
__construct()
для данного класса, он будет искать функцию конструктора старого стиля по имени класса.Фактически это означает, что единственным случаем, который имел бы проблемы с совместимостью, является то, что у класса был метод с именем
__construct()
который использовался для различной семантики.
Итак, я действительно думаю, что не так уж много разницы 🙂
Вы столкнулись с какой-то странной проблемой, которая, по вашему мнению, вызвана чем-то вроде разницы между двумя синтаксисами?
Начиная с PHP 5.3.3 старый стиль ctor не будет работать, если вы используете пространства имен.