note 46586 deleted from language.oop5.reflection by curt

From: Date: Sat, 16 Oct 2004 05:40:38 +0000
Subject: note 46586 deleted from language.oop5.reflection by curt
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-78647@lists.php.net to get a copy of this message
Note Submitter: russ dot collier at NOSPAM dot 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, and calling static methods on variable classnames produces a PHP syntax error :-) such as $className::staticMethod()), you can do something like this example below, using the PHP5 Reflection API: <?php abstract class Shape { /** * Implicitly will throw an Exception from the Reflection API */ 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() { } } /** * .... Client/user code */ $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 these new subclasses in the Shape::makeShape() factory method :-) 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, but before the Reflection API is called: <?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( "/path/to/your/php/class/include/files/class_$shapeName.php" ); ?> ---- Reason: bad code

« previous php.notes (#78647) next »