I'm designing a series of classes, a single base class and several inheriting "driver" classes. The base class handles common operations such as making a socket connection, and sending and receiving data. The individual "driver" classes extend the base, but handle specific cases, such as handling different protocols of messages sent and received over said socket.

The module itself is fairly complex, but I'd like its usage to be simple, such that someone instantiates the base class, giving a driver name as an argument, and what is returned is actually an instance of the driver.

I have no problems dynamically including and instantiating the driver class from within the base class' constructor, which i'm currently assigning to a property of the base object:

class MyBase {
  // where to store driver class object
  public $driver = NULL;

  // base class constructor (inherited by driver classes)
  public function __construct($driver = NULL, $arguments = NULL) {

// if in the base class, include and instantiate the descendant class
if (get_class($this) == 'MyBase') {
  // if no driver classname provided, die
  if(is_null($driver)) {
    die('no driver name provided');
  }

  // if driver contains anything that doesnt match a \w pattern, die
  if(!preg_match('/^\w+$/', $driver)) {
    die("invalid driver name provided: '$driver'");
  }

  // build the driver's classname and filename
  $drv_class = implode('', array('MyBase_', $driver));
  $drv_filename = implode('', array($drv_class, '.inc.php'));

  // include and instantiate the driver class
  include($drv_filename);
  $this->driver = new $drv_class();
  return;
}

// this is where we do stuff for the driver (making connections, etc)...
  }

}

However, I can't figure out if and how to simply have the new MyBase() return the driver object instead. At the moment, this is the usage:

// instantiate MyBase, using Driver1 inherited class
$object = new MyBase('Driver1', $other_args);

// get the useful object of class MyBase_Driver1
$real_object = $object->driver;

But this is what I'd like to do for an interface:

// instantiate MyBase, using Driver1 inherited class
$object = new MyBase('Driver1', $other_args);

// should already *be* an object of MyBase_Driver1
var_dump($object );

Simply put, is this possible? If so, how? I'd appreciate any help, thanks for reading through all this long-windedness!

    What you want is to supply the parent class with a static method that calls the appropriate subclass's constructor, returning the object that results. (The parent class then acts like a so-called "Factory" that cranks out drivers).

    $object = MyBase::NewDriver('Driver1', $other_args);
    
    public static function NewDriver($driver_name, $other_args)
    {
       if(class_exists($driver_name) && is_subclass_of($driver_name, 'MyBase'))
       {
          return new $driver_name($other_args);
       }
    }
    
      Write a Reply...