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.
In order to run a parent constructor, a call to parent::__construct() within the child constructor is required. If the child does not define a constructor then it may be inherited from the parent class just like a normal class method (if it was not declared as private). $obj = new OtherSubClass();
PHP - The __construct Function A constructor allows you to initialize an object's properties upon creation of the object. If you create a __construct() function, PHP will automatically call this function when you create an object from a class. Notice that the construct function starts with two underscores (__)!
We can do this by using the special function call parent::__construct(). The "parent" part means "get the parent of this object, and use it", and the __construct() part means "call the construct function", of course. So the whole line means "get the parent of this object then call its constructor".
Inheritance: As Inheritance is an object-oriented concept, the Constructors are inherited from parent class to child class derived from it.
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 :
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With