note 46634 deleted from language.oop5.reflection by danbrown
| From: | danbrown@php.net | Date: | Wed, 16 Sep 2009 16:19:24 +0000 |
| Subject: | note 46634 deleted from language.oop5.reflection by danbrown | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-160725@lists.php.net to get a copy of this message | ||
Note Submitter: russ dot collier at gmail dot com
----
If you've ever wanted to do dynamic class loading in PHP5, especially when the class
you're trying to dynamically load is a Singleton (and therefore you cannot use the new
operator), you can do something like this example below, using the PHP5 Reflection API:
<?php
abstract class Shape
{
static public function makeShape( $shapeName )
{
$shapeInstance = null;
$shapeClass = new ReflectionClass( $shapeName );
$shapeMethod = $shapeClass->getMethod( 'getInstance' );
$shapeInstance = $shapeMethod->invoke( null );
$shapeClass = null;
$shapeMethod = null;
return $shapeInstance;
}
abstract public function doStuff();
}
class Triangle extends Shape
{
private static $instance = null;
private function __construct() { }
public static function getInstance()
{
if ( null == self::$instance )
{
self::$instance = new self;
}
return self::$instance;
}
public function doStuff() { }
}
$typeOfShape = 'Triangle';
$shape = null;
try
{
$shape = Shape::makeShape( $typeOfShape );
}
catch ( Exception $e )
{
print "Error creating shape '$typeOfShape'! " . $e->getMessage() .
"\n";
}
if ( null != $shape )
{
// $shape will be an instance of Triangle
$shape->doStuff();
}
?>
So by changing the value of $typeOfShape you can dynamically load the appropriate Shape subclass at
runtime, thus facilitating a sort of plug-in style architecture for your classes. You can just drop
in new Shape subclasses and not have to modify any of the Shape class code to support them in its
factory method makeShape() :-)
If your subclasses are all in separate files, you could even make the 'including' of these
files dynamic as well, by adding these lines to the Shape::makeShape() method after the
$shapeInstance is initialized:
<?php
ini_set( 'include_path', ini_get( 'include_path' ) . PATH_SEPARATOR .
'/path/to/your/php/class/include/files' );
/**
* Assuming your subclasses are in files called 'class_$shapeName.php' :-)
* Of course doing a dynamic require() could be a security problem depending
* on how you validate/clean your $shapeName method parameter (if at all ;-))
*/
require_once( "class_$shapeName.php" );
?>