Calling PHP Parent Constructors With Old/New Syntax
Is there any functional difference between calling the parent constructor with a new style constructor or the old style constructor?
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.
2 Answers 2
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();
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.
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 ?
Call Parent Class construct Before Child’s In PHP
If in PHP, you are making a child class of a parent class in which both have the __construct function and you want to call both of them when the child object is made, it won’t work.
This is because, when you make the child class object, it’s construct function is called. The parent’s construct function is being overridden by the child. The PHP manual on OOP (Object Oriented Programming) notes this :
Note: Parent constructors are not called implicitly if the child class defines a constructor. 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).
So, the parent’s construct function is not called if w’re making the child object.
Classes
This is the parent class named «MyParentClass» :
class MyParentClass < public $myVal = 0; function __construct()< $this->myVal = 1; > >
And we extend it to make the child class named «MyChildClass» :
class MyChildClass extends MyParentClass < function __construct()< echo $this->myVal; > >
Now, when you make the child object, the output made by echo will be nothing but **** :
(We’re using direct echo and not return).
Reason
In the parent class, we make a public variable called «myVal» which is set to 0. When the parent class is made by this :
the value of MyParentClass::myVal is changed to «1». This change only takes effect if the parent class is made and not the child class. So, when you make the child class, the output will be **** and not 1.
Solution
But, you can also make changes first in the parent class and then do the code in MyChildClass::__construct(). For this, we add the following code as the first code in MyChildClass::__construct() :
And the whole child class will become :
class MyChildClass extends MyParentClass < function __construct()< parent::__construct(); echo $this->myVal; > >
Don’t be worried about the constant parent, because it’s built in and it defines the parent class from which we are extending the main class.
Now, when you make the child class, the output will be 1 because the parent __construct() is called before the code in child’s __construct() is ran.
You can apply the same solution in your child classes, so that parent and class is linked instead of going separate ways.