【发布时间】:2014-02-12 21:49:00
【问题描述】:
我正在使用已用于部署多个网站的现有代码库。一些站点自定义了一些类。我已经构建了一个至少可以找到类的自动加载函数。不幸的是,有些类在构造函数中有不同数量的参数。此时要“正确”所有这些类以使它们具有相同的构造函数签名是不切实际的。
除了自动加载器(它正在工作)之外,我正在尝试构建一个将实例化基本类的工厂。工厂应该处理对“购物车”类的请求,并传回该特定站点上使用的任何购物车类的实例。构造函数中不同数量的参数混淆了代码。我正在寻找一种方法来清理最后一部分(请参阅下面代码中的 cmets)。
/**
* find and instantiate an object of the type $classtype.
* example usage: factory::instance('cart');
*
* @param string $classtype the class to instantiate
* @param array $options optional array of parameters for the constructor
* @return object
* @throws Exception
*/
static public function instance($classtype, $options = array()) {
// so you request an instance of 'cart'
// if CART_CLASS is defined, we set the class name to the value of that constant
// if CART_CLASS is not defined, we set the class name to basic_cart
$define = strtoupper("{$classtype}_CLASS");
$class = defined($define) ? constant($define) : strtolower("basic_$classtype");
$reflection = new ReflectionClass($class); // autoload function kicks in here to find the class
// get the parameter list for the constructor
$parameters = $reflection->getConstructor()->getParameters();
$p = array();
foreach($parameters as $parameter) {
if(array_key_exists($parameter->name, $options)) {
// making sure the order is correct by creating a new array
$p[] = $options[$parameter->name];
} else {
if($parameter->isOptional()) {
break; // todo: get the default value and pass that on instantiation
} else {
throw new Exception("required parameter '{$parameter->name}' was not provided in the options array when loading $class");
}
}
}
// todo: there must be a better way to pass a variable number of parameters
if(count($p) == 1) {
return new $class($p[0]);
} else if(count($p) == 2) {
return new $class($p[0], $p[1]);
} else if(count($p) == 3) {
return new $class($p[0], $p[1], $p[2]);
} else if(count($p) == 4) {
return new $class($p[0], $p[1], $p[2], $p[3]);
} else {
return new $class();
}
}
下面是一个实例的“请求”示例。
$c = factory::instance('cart');
$s = factory::instance('ship_controller', array('cart' => $c));
对上面代码的所有部分的评论都很好,但我真的在为最后一部分寻找更好的解决方案。迟早会碰到一个有五个参数的类,“return new $class($p[0], $p[1], $p[2], $p[3]);”已经烦我了。
【问题讨论】:
标签: php reflection factory autoloader