我有一个扩展基类控制器类的子控制器类。在子代码中,我定义了一个静态命名空间字符串,该字符串指向我在基类中调用函数时要使用的模型类。现在,我必须使用call_user_func
来调用正确的模型类上的函数。代码看起来像这样:
class RolesController extends Controller
{
const RESOURCE_NAME = 'roles';
const MODEL = 'Role';
}
class Controller extends BaseController
{
private $model;
public function __construct()
{
$this->model = 'App\\Models\\' . static::MODEL;
}
public function getAll(Request $request)
{
$objects = call_user_func([$this->model, 'getAll'], [
Model::GET_OPTION_FORMAT => true
]);
return Response::success([
static::RESOURCE_NAME => $objects
]);
}
}
我不禁认为这种设计模式不正确。有没有更好的方法来完成我想要做的事情而不必依赖call_user_func
?我找不到类似的问题,因为我正在努力找到描述这个问题的词。如果有人能指出我正确的方向,将不胜感激。
答案 0 :(得分:2)
这使得繁琐的是模型类上的静态方法。更清洁的方法可能如下所示:
class RolesController extends Controller
{
const RESOURCE_NAME = 'roles';
const MODEL = App\Models\Role::class;
}
class Controller extends BaseController
{
private $model;
public function __construct()
{
$modelClass = static::MODEL;
$this->model = new $modelClass;
}
public function getAll(Request $request)
{
$objects = $this->model->getAll([
Model::GET_OPTION_FORMAT => true
]);
return Response::success([
static::RESOURCE_NAME => $objects
]);
}
}
我将"模型类保持为常数"方法,但它明确地引用了这个类。
但是现在我们正在使用实际的对象,我建议更进一步,在没有类常量间接的情况下实例化它:
class RolesController extends Controller
{
const RESOURCE_NAME = 'roles';
public function __construct()
{
parent::__construct();
$this->model = new App\Models\Role();
}
}
class Controller extends BaseController
{
protected $model;
public function __construct()
{
}
public function getAll(Request $request)
{
$objects = $this->model->getAll([
Model::GET_OPTION_FORMAT => true
]);
return Response::success([
static::RESOURCE_NAME => $objects
]);
}
}
请注意,您不需要将静态方法getAll
更改为非静态方法。使用$object->method
调用静态方法即使在严格模式下也能正常工作(不是相反)。
你也可以使用变量作为类名(不是属性,正如你所尝试的那样,解析器无法理解这一点):
$class = $this->model;
$objects = $class::getAll([
Model::GET_OPTION_FORMAT => true
]);
但这只能解决你的直接编码问题,而不能解决结构问题。