Given the class Foo with an old-style constructor
class Foo
{
public function Foo()
{
//does constructing stuff
}
}
Is there any functional difference between calling the parent constructor with a new style constructor or the old style constructor?
class Bar extends Foo
{
public function Bar()
{
//does it matter?
//parent::__construct();
//parent::Foo();
}
}
Put another way, is there anything special about the static call
parent::__construct()
when it's made from a constructor, or is it just a standard static call?
Before the Best Practices Flying Monkeys descend, I'm dealing with some legacy code and trying to understand the consequences of everything that's going on.
I would say both syntax do exactly the same thing...
Edit : after writting the rest of the answer, actually, this is not entirely true ^^ It depends on what you declare ; see the two examples :
If you define Foo
as constructor, and call it with __construct
, it seems it's working ; the following code :
class Foo {
public function Foo() {
var_dump('blah');
}
}
class Bar extends Foo {
public function Bar() {
parent::__construct();
}
}
$a = new Bar();
Outputs
string 'blah' (length=4)
So, all OK for now ;-)
On the other way, if you define __construct, and call Foo, like this :
class Foo {
public function __construct() {
var_dump('blah');
}
}
class Bar extends Foo {
public function Bar() {
parent::Foo();
}
}
$a = new Bar();
It'll get you a Fatal Error :
Fatal error: Call to undefined method Foo::foo()
So, if your class is declared with old-syntax, you can call it both ways ; and if it's defined with new (PHP5) syntax, you must use that new syntax -- which makes sense, afterall :-)
BTW, if you want some kind of "real proof", you can try using the Vulcan Logic Disassembler, that will give you the opcodes corresponding to a PHP script.
EDIT after the comment
I've uploaded the outputs of using VLD with both syntaxes :
- vld-construct-new.txt : when declaring __construct, and calling __construct.
- vld-construct-old.txt : when declaring Foo, and calling __construct.
Doing a diff between the two files, this is what I get :
$ 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.
(Unified diff is much longer, so I'll stick to using the default format of "diff" here)
So, the only differences in the disassembled opcodes are the names of the functions ; both in the Foo
class and in the Bar
class (that inherits the __construct
/ Foo
method of class Foo
).
What I would really say is :
- If you are writting PHP 5 code (and, in 2009, I sincerely hope you do ^^ ), then, just use the __construct syntax
- You you have to maintain some old PHP 4 code you can't migrate to PHP 5 (you should), then, use the Foo syntax...
As the sidenote, the documentation says (quoting) :
For backwards compatibility, if PHP 5
cannot find a __construct()
function
for a given class, it will search for
the old-style constructor function, by
the name of the class.
Effectively, it means that the only
case that would have compatibility
issues is if the class had a method
named __construct()
which was used
for different semantics.
So, I really think there is not that much of a difference :-)
Did you encounter some kind of strange problem, that you think is caused by something like a difference between the two syntaxes ?
As of PHP 5.3.3 the old style ctor will not work when you are using namespaces.
See http://www.php.net/archive/2010.php#id2010-07-22-2