我正在使用已用于部署多个网站的现有代码库。一些网站定制了一些类。我已经构建了一个至少可以找到类的自动加载功能。不幸的是,一些类在构造函数中具有不同数量的参数。此时要“纠正”所有这些类以使它们具有相同的构造函数签名是不切实际的。
除了自动加载器(正在工作)之外,我正在尝试构建一个将实例化基本类的工厂。工厂应该处理“cart”类的请求,并传回该特定站点上使用的任何购物车类的实例。构造函数中不同数量的参数使代码变得混乱。我正在寻找一种方法来清理最后一部分(请参阅以下代码中的注释)。
/**
* 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));
对上面代码的所有部分的评论很好,但我真的在寻找更好的解决方案。迟早,我会遇到一个有五个参数的课程并且“返回新的$ class($ p [0],$ p [1],$ p [2],$ p [3]);”已经让我很恼火。
答案 0 :(得分:2)
简单:
return $reflection->newInstanceArgs($p);