PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!
public function load_obj( $class, $handle, $args = null){
if(class_exists($class)){
$obj = $$handle = new $class;
}
$this->set_obj( $obj, $handle );
}
I'm trying to write a method that dynamically instantiates a class.
This little bit I wrote works. It creates an object. But what I haven't been able to get work is adding $args to $class for constructor arguments. I'm not sure how this is done. Every string solution I've tried has failed. (I've tried making args an array and implode it to a string.) Any ideas?
EDIT: Oh and I actually don't even use that class now
But instead I have turned that class into an abstract class and subclassed registries for more specific tasks.... (request, session, etc) and then I use __autoload in combination with pear naming to load the classes. Works well
arborint wrote:The eval method allows any number of args. Usually $arglist is built from args from the variable arg functions. The second only allows one arg.
Note - There is a loop before the eval() that builds the $arglist.
Just discovered that one for myself. It must be the comma that is not evaluated as code but as a string.
Thanks to you and the Space Goat for exploring this pattern to the hilt. I think I've found most of what I was looking for.
And yes __autoload for PHP 5 is the way to go for inclusion -- it being triggered by class_exists()
class gg_registry{
private $stack;
/**
* Everything needed to instantiate the requested class
* Thanks to "The Ninja Space Goat" and "Aborint" at
* devnetwork for their help on this method.
*
* @static
* @param $class The name of the class to instantiate
* @param $handle The name of the object
* @param array $args an array of arguments to pass to the constructor
*/
public function load_obj($class, $handle, array $args) {
$argslist = array();
if(class_exists($class)){
if( empty($args) ){
$obj = $$handle = new $class;
} else {
//Arguments to process
$n = count($args);
for ($i=0; $i<$n; ++$i) {
$arglist[$i] = "\$args[$i]";
}
eval ("$" . "object = new {$class}(" . implode(', ', $arglist) . ');');
}
}
$this->set_obj( &$object, $handle);
}
/**
* This function is used for retrieving the registry obj in
* preparation for accessing objects it holds.
*
* @return object returns a registry object
*/
public static function &instance(){
static $reg;
if (!$reg){
$reg = new gg_registry;
}
return $reg;
}
/**
* Adds objects and variables to the stack. Use if the object is already
* instantiated. Works great for data objects or when load_obj for whatever
* reason doesn't yield desirable results.
*
* @access public
* @param object $object the object to be inserteregistry_test.phpd into the $GLOBALS container
* @param string $handle optional name of class to be made globally accessible
*/
public function set_obj( &$object, $handle = '' ){
$class = (empty($handle))? get_class($object): $handle;
$this->stack[$class] = $object;
}
/**
* A "getter" for retrieving objects from the registry.
*
* @access public
* @param string $handle The name of the class to retrieve from the $GLOBALS array or the handle for the variable
*/
public function &get_obj($handle){
return $this->stack[$handle];
}
} // end class
/**
* Automatically includes code for requested class
*
* @param string $classname
*/
function __autoload($classname){
if(strstr($classname, 'module')){
$path = $_SERVER['DOCUMENT_ROOT'].'modules/';
} else {
$path = $_SERVER['DOCUMENT_ROOT'].'lib/';
}
$ext = ".php";
$classname = substr_replace( $classname, '',0,3);
include_once($path.$classname.$ext);
}
We started a thread around there to take a Registry to the next level and turn it into a Service Locator. I made a list of requirements. If we could come up with a Service Locator then Dependency Injection is just around the corner.