views:

31

answers:

3

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);
A: 

Umm, wouldn't that be:

class sub extends parent {
  public static function make_objects($conditions) {
    //sub specific stuff here
    //....
  }
}
Jumby
oh i see i forgot the extends in my example code.but no.the make objects is goin to be quite long and compex and there are going to be dozens of subclasses of parent so putting the whole method in each subclass is highly undesirable (although it may turn out to be the only option)
Martijn v E
+1  A: 

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
VolkerK
But as I understand him he wants to create instances depending on the type he has in his database. So this would not help him either.
Sebastian Hoitz
Maybe, the question is a bit vague. We'll see.
VolkerK
no i want to create instances of sub but for lines in my database so it hink this is the answer i was hoping for. Going to test it now.
Martijn v E
Tested it and its just what i was looking for, thanks a million.
Martijn v E
A: 

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?

Sebastian Hoitz