<?php
class Super {
public $my;
public function __construct ( $someArg ) {
if ( class_exists('Sub') ) { // or some other condition
return new Sub( $someArg );
}
$this->my = $someArg;
}
}
class Sub extends Super {}
?>
This doesn't work, as new Super()
will be an "empty" Super
object (all members are NULL
). (PHP doesn't allow assignments to $this
, so $this = new Sub()
doesn't work either).
I know the correct pattern would be a factory here. But that would require a lot of changes in the code, so I'm wondering whether it's possible to do it this way. Since Sub
is-a Super
, I don't see why it shouldn't be restricted from an OOP point of view.
You can't assign to $this
and you cannot return anything from a constructor.
You got something wrong here. The constructor does not have a return value, you cannot return an instance from the constructor - once the constructor is called, the class is settled, you cannot change it any more.
What you want to do is to implement the factory pattern for this:
<?php
class Super {
public $my;
public function __construct ( $someArg ) {
$this->my = $someArg;
}
public static function factory ($somearg) {
if ( class_exists('Sub') && $somearg["foo"] == "bar") { // or some other condition
return new Sub( $someArg );
}
else {
return new Super($someArg);
}
}
}
class Sub extends Super {}
$mynewsuborsuper = Super::factory($myargs);
?>
Use PHP reflection. No need for switches or inheritance when you're using a factory.
<?php
class DocumentFactory
{
public function create($className, $constructorArguments = array())
{
$reflection = new ReflectionClass($className);
return $reflection->newInstanceArgs($constructorArguments);
}
}
abstract class Document
{
$protected $doc;
public function __construct($string){$this->doc = $string;}
}
class XMLDocument extends Document
{
public function __construct($string, $extraArg)
{
parent::__construct($string);
//Do something else with $extraArg
}
}
class HTMLDocument extends Document
{
}
$DFactory = new DocumentFactory();
$XMLDocument = $DFactory->create('MY\FULL\NAMESPACE\XMLDocument', array(//extra arguments));
//Or add .php at the end if you're not using namespaces