Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP: call child constructor from static method in parent

I want to have a static method in a parent class that creates instances of whatever subclass i call this method on.

An example to make this more clear:

class parent {
    public static method make_objects($conditions){
        for (...){
            // here i want to create an instance
            // of whatever subclass i am calling make_objects on
            // based on certain $conditions
        }
    }
}

class sub extends parent{
    ...
}

$objects = sub::make_objects($some_conditions);
like image 740
martijnve Avatar asked Aug 02 '10 20:08

martijnve


People also ask

How can we call a constructor from parent class in PHP?

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();

How do you call a child constructor?

You can call the base class constructor from the child class by using the super() which will execute the constructor of the base class. Example: Javascript.

Does child constructor call parent constructor?

If parent class implements a constructor with arguments and has no a constructor with no arguments, then the child constructors must explicitly call a parents constructor.

Can we have same static method in parent and child class?

We can declare static methods with the same signature in the subclass, but it is not considered overriding as there won't be any run-time polymorphism. Hence the answer is 'No'.


2 Answers

As of php 5.3 you can use the static keyword for this

<?php
class A {
  public static function newInstance() {
    $rv = new static();  
    return $rv;
  }
}
class B extends A { }
class C extends B { }

$o = A::newInstance(); var_dump($o);
$o = B::newInstance(); var_dump($o);
$o = C::newInstance(); var_dump($o);

prints

object(A)#1 (0) {
}
object(B)#2 (0) {
}
object(C)#1 (0) {
}

edit: another (similar) example

<?php
class A {
  public static function newInstance() {
    $rv = new static();  
    return $rv;
  }

  public function __construct() { echo " A::__construct\n"; }
}
class B extends A {
  public function __construct() { echo " B::__construct\n"; }
}
class C extends B {
  public function __construct() { echo " C::__construct\n"; }   
}

$types = array('A', 'B', 'C');
foreach( $types as $t ) {
  echo 't=', $t, "\n";
  $o = $t::newInstance();
  echo '  type of o=', get_class($o), "\n";
}

prints

t=A
 A::__construct
  type of o=A
t=B
 B::__construct
  type of o=B
t=C
 C::__construct
  type of o=C
like image 180
VolkerK Avatar answered Sep 18 '22 18:09

VolkerK


I think you want something like this:

class parent {
  public static function make_object($conditionns) {
    if($conditions == "case1") {
      return new sub();
    }
  }
}

class sub extends parent {

}

Now you can create an instance like this:

$instance = parent::make_object("case1");

or

$instance = sub::make_object("case1");

But why would you want all the sub classes to extend the parent? Shouldn't you much rather have a parent for your models (sub classes) and then a factory class, that creates the instances for this models depending on the conditions given?

like image 31
Sebastian Hoitz Avatar answered Sep 18 '22 18:09

Sebastian Hoitz