Calling the parent constructor from a child class automatically.

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • dlite922
    Recognized Expert Top Contributor
    • Dec 2007
    • 1586

    Calling the parent constructor from a child class automatically.

    If I have

    [PHP]
    class Parent
    {
    function __construct()
    {
    die("I'm In Parent");
    }

    }

    class Child extends Parent
    {
    function __construct()
    {
    echo "going through child constructor..." ;
    }
    }

    $test = new Child();

    [/PHP]

    The above code does not print the die statement.

    I expected it to do so. Bug or By Design?
    Last edited by Atli; Jun 14 '08, 09:39 PM. Reason: Changed the thread title to better explain it's contents.
  • realin
    Contributor
    • Feb 2007
    • 254

    #2
    I believe PHP calls its nearest constructor. if you need to call constructor from parent you can explicitly call it using parent::__const ructor();

    So if the child (extending class) doesn't have any constructor then it calls parent constructor by default. Same goes for the case of grandparent constructor. See for example ::
    [PHP]
    <?
    class top{
    function __construct()

    {

    echo ("I'm In GrandParent");

    }
    }
    class A extends top

    {




    }


    class Child extends A

    {

    }

    $test = new Child();

    ?>[/PHP]

    now for your piece of code we can call the parent constructor using the following snippet of code ::
    [PHP]
    <?
    class A

    {

    function __construct()

    {

    die("I'm In Parent");

    }

    }
    class Child extends A

    {

    function __construct()

    {

    echo "going through child constructor..." ;
    parent::__const ruct();
    }

    }

    $test = new Child();

    ?>[/PHP]


    hope this helps :)
    cheers !!

    Comment

    • dlite922
      Recognized Expert Top Contributor
      • Dec 2007
      • 1586

      #3
      Originally posted by realin
      I believe PHP calls its nearest constructor. if you need to call constructor from parent you can explicitly call it using parent::__const ructor();

      So if the child (extending class) doesn't have any constructor then it calls parent constructor by default. Same goes for the case of grandparent constructor. See for example ::
      [PHP]
      <?
      class top{
      function __construct()

      {

      echo ("I'm In GrandParent");

      }
      }
      class A extends top

      {




      }


      class Child extends A

      {

      }

      $test = new Child();

      ?>[/PHP]

      now for your piece of code we can call the parent constructor using the following snippet of code ::
      [PHP]
      <?
      class A

      {

      function __construct()

      {

      die("I'm In Parent");

      }

      }
      class Child extends A

      {

      function __construct()

      {

      echo "going through child constructor..." ;
      parent::__const ruct();
      }

      }

      $test = new Child();

      ?>[/PHP]


      hope this helps :)
      cheers !!
      Yeah thanks, I knew you could manually call it, but what's the point of having a constructor then. Defeats the purpose of automation.

      I could place my task in a different function and call that instead.

      I"m disappointed, this ruined my chance of a good framework I am building.

      Thanks,

      Dan

      Comment

      • realin
        Contributor
        • Feb 2007
        • 254

        #4
        yup..
        its doesn't call it automatically.. jus like it happens in java
        may be there is some solution out ..

        Comment

        • Atli
          Recognized Expert Expert
          • Nov 2006
          • 5062

          #5
          I don't get the problem.

          Why would you want the parent constructor to be called automatically?
          Even as it is not, would it not be just as effective to create a constructor that calls it's parent constructor?

          Comment

          • realin
            Contributor
            • Feb 2007
            • 254

            #6
            Originally posted by Atli
            I don't get the problem.

            Why would you want the parent constructor to be called automatically?
            Even as it is not, would it not be just as effective to create a constructor that calls it's parent constructor?
            agreed.. cause that way you have a choice .. cause this gives you both options:

            To call a parent constructor, if needed
            Parent constructor do not gets called by default


            But in case of java, i see no way u can ask proggie not to call Parent constructor if it exists in there.. Correct me if i am wrong ..

            Comment

            • dlite922
              Recognized Expert Top Contributor
              • Dec 2007
              • 1586

              #7
              Originally posted by realin
              agreed.. cause that way you have a choice .. cause this gives you both options:

              To call a parent constructor, if needed
              Parent constructor do not gets called by default


              But in case of java, i see no way u can ask proggie not to call Parent constructor if it exists in there.. Correct me if i am wrong ..
              Okay you need a scenario, take mine.

              I"m using my home-cooked MVC architecture and I keep building it.

              Most of my pages have a few variables that I need to check for each single time. This is the "pageAction " variable. 99% of pages will have it.

              I wanted to automatically get this pageAction from POST and put it in a var in the parent, that way the child controller does not have to do this everytime...hen ce automation.

              If I have to call some constructor, or some function, I could just make it a rule and make sure each controller child class grabs the pageAction (They always have to if the page is not static)

              For example here's a .php page that uses a customer controller (CT)
              (I'm just typing this as i go and is not actual code)
              [PHP]

              //my includes
              require_once("b lah.php"); //etc...

              $customerCT = new CustomerCT();

              switch($custome rCT->getPageAction( ))
              {
              case "Add":
              $customerCT->add();
              break;
              case "Update":
              $customerCT->update();
              break;
              }

              $smrty->dispay("custom er.tpl");


              [/PHP]

              That's an over-simplified version of my architecture. In the constructor of CustomerCT I get POST variables that are specific to that page. "pageAction " is very common, exists on all pages with a submit button.

              How do other frameworks do it (Cake, Zend, Symphony).

              In the global include, or index.php file, they just grab it and put it in a global variable?

              I guess that's one way.

              So I could do

              [PHP]

              switch(PAGE_ACT ION)
              {
              case "Add" ....

              [/PHP]

              I guess that would work...yes? is it cleaner?

              pbmods is good at ZendF, hopefully he can shed some light on this.

              Thanks guys,

              Dan

              Comment

              • Atli
                Recognized Expert Expert
                • Nov 2006
                • 5062

                #8
                I would do it inside the Control object. Somewhat like:
                [code=php]
                class BaseCT {
                protected $action;
                public function __construct() {
                $this->action = @$_GET['action'];
                // And whatever other global CT constructor logic
                }
                }

                class SomepageCT extends BaseCT {
                public function __construct() {
                parent::__const ruct();
                // And whatever specialized constructor logic
                }

                public function execute() {
                switch($this->$action) {
                case "Add":
                $this->_addSomething( );
                break;
                case "Edit":
                $this->_editSomething ();
                break;
                default:
                $this->_displaySometh ing();
                break;
                }
                }

                // Plus the private functions used by the execute method.
                }
                [/code]
                Then I could call all pages somewhat like:
                [code=php]
                $className = (isset($_GET['page']) ? $_GET['page'] ."CT" : "DefaultCT" );
                $page = new $className();
                $page->execute();
                [/code]
                Is this not basically what you were trying to do?

                Comment

                • dlite922
                  Recognized Expert Top Contributor
                  • Dec 2007
                  • 1586

                  #9
                  Originally posted by Atli
                  I would do it inside the Control object. Somewhat like:
                  [code=php]
                  class BaseCT {
                  protected $action;
                  public function __construct() {
                  $this->action = @$_GET['action'];
                  // And whatever other global CT constructor logic
                  }
                  }

                  class SomepageCT extends BaseCT {
                  public function __construct() {
                  parent::__const ruct();
                  // And whatever specialized constructor logic
                  }

                  public function execute() {
                  switch($this->$action) {
                  case "Add":
                  $this->_addSomething( );
                  break;
                  case "Edit":
                  $this->_editSomething ();
                  break;
                  default:
                  $this->_displaySometh ing();
                  break;
                  }
                  }

                  // Plus the private functions used by the execute method.
                  }
                  [/code]
                  Then I could call all pages somewhat like:
                  [code=php]
                  $className = (isset($_GET['page']) ? $_GET['page'] ."CT" : "DefaultCT" );
                  $page = new $className();
                  $page->execute();
                  [/code]
                  Is this not basically what you were trying to do?
                  Yeah you've got the right idea. Mine does the same thing as well if i call parent::__const ruct() inside each of my child's constructors.

                  I was trying to avoid that.

                  Comment

                  • Mikeemoo
                    New Member
                    • Jul 2008
                    • 2

                    #10
                    to force the call of a parent constructor you can use the 'final' keyword on the parents constructor.

                    of course, this means it can NEVER be overwritten, so use with caution.

                    [PHP]
                    class A {
                    final function __construct ($my,$args){
                    die("i've been called");
                    }
                    }
                    class B extends A{

                    }

                    $myobj = new B("hello", "world");

                    // i've been called
                    [/PHP]

                    Comment

                    • Mikeemoo
                      New Member
                      • Jul 2008
                      • 2

                      #11
                      actually now that i've said that i don't think it's true.

                      possibly ignore me.

                      (he says 1 month after OP asked the question..)

                      Comment

                      • Atli
                        Recognized Expert Expert
                        • Nov 2006
                        • 5062

                        #12
                        Actually, what happens is that when the child class does not have a constructor, the parent constructor will be called automatically.

                        Adding the "final" keyword the the constructor of the parent only prevents the constructor from being overridden. It will be called by default whether it is final or not.

                        So that really doesn't change anything. If you create a constructor for the child, the parent constructor will not be called unless you call it manually.

                        Comment

                        Working...