views:

63

answers:

4

Hey all,

I was wondering if its possible to call the parents __construct(), before the child's __construct() with inheritance in PHP.

Example:

class Tag {
     __construct() {
         // Called first.
     }
}

class Form extends Tag {
     __construct() {
         // Called second.
     }
} 

new Form();

Ideally, I would be able to do something in between them. If this is not possible, is there an alternative, which would allow me to do this?

The reason I want to do this is to be able to load a bunch of default settings specific to the Tag that Form can use when __construct() is called.

EDIT: Sorry forgot to add this.. I'd rather not call the parent class from the child class. It's simply because it exposes some private data (for the parent) to the child, when you pass it as an argument

This is what I want to do:

$tag = new Tag($privateInfo, $publicInfo);
$tag->extend(new Form()); // Ideal function, prob doesn't work with inheritance.

Tag.php

class Tag {
     private $privateInfo;
     public $publicInfo;
     __construct($private, $public) {
         $this->privateInfo = $private;
         $this->publicInfo = $public;
     }
} 

Form.php

class Form extends Tag {

     __construct() {
         echo $this->publicInfo;
     }
} 

Make sense?

Thanks! Matt Mueller

+2  A: 

yeah just call parent::__construct() in your construct

Pentium10
Ahh sorry I forgot to include a requirement... Please read the edit for update.
Matt
This is the way to do, simply read OOP manual if you don't agree. Don't try to reinvent the wheel. If you have concern regarding your model, try to post that too, to see how you did. Probably you are doing a bad design technique.
Pentium10
I'm not trying to reinvent the wheel... I'm trying to get a solution to my requirements.
Matt
I reread your edited question, but still don't understand what problems you have. What data is visible to the child class from parent? Maybe you should post a bad example, with some echo to see what do you see wrong.
Pentium10
+5  A: 

Just call parent::__construct in the child.

class Form extends Tag
{
    function __construct()
    {
        parent::__construct();
        // Called second.
    }
}
Denis 'Alpheus' Čahuk
Ahh sorry. I forgot to add that I would rather not have that in the child's constructor. Please read edit.
Matt
Decided that this was the best of the alternatives. Unfortunately, its not exactly what I wanted - oh well.. Thanks!
Matt
Oh wow Denis, you have been really helping me out the last couple days.. Thanks man!
Matt
+2  A: 

Yes, but only internally (i.e., by writing a PHP extension), so if I were you I'd settle with calling parent::__construct(). See this section on the PHP wiki.

Sorry, PHP is not Java. I think not requiring (implicitly or explictly) the super constructor to be called was a very poor design decision.

Artefacto
+1  A: 

From the sounds of it you may want to rethink your design so that you don't need to pass the parameters in the constructor. If you don't think it can be done, ask it as a question, you might be surprised by some of the suggestions.

The child class has the ability to override the parent constructor without calling it at all. I would recommend having a final method in the parent class. That way everyone knows you don't want this being overriden, and any inherited class (rightly) has access to do whatever it wants in the constructor.

class Father {
    private $_privateData;
    final function setPrivateData($privateData) {
        $this->_privateData = $privateData;
    }
}

Another, not recommended, more "reinventing the wheel", solution would be to define a function in the parent class, say _construct(), that's called in its own construct. Its not really clear, doesn't use language features/constructs, and is very specific to a single application.

One last thing to keep in mind: you can't really hide information from the child class. With Reflection, serialize, var_dump, var_export and all these other convenient APIs in the php language, if there is code that shouldn't do anything with the data, then there's not really much you can do asides from not store it. There are libraries and such that help create sandboxes, but its hard to sandbox an object from itself.

Edit: Somehow I missed Artefacto's answer, and I suppose he is right (I've never tried writing an extension to do that). Still, implementing it breaks developer expectations while making it harder to actually see code to explain what's going in.

AlReece45
Hey, thanks for your response. Unfortunately this topic got a little out of hand, which is my fault. Anyways, I am trying to redesign it. I have a question about your answer... how can you do this - "The child class has the ability to override the parent constructor without calling it at all."?
Matt
@Matt You can't using just PHP code. The person writing the derived class has the ability to not call the parent constructor at all. What you could do for a project is have another function defined that gets called by the parent class in its constructor, say _construct() which the parent defines and calls.
AlReece45