这里有一些我不明白的地方。我在视频教程的基础上构建了一个非常酷的路由器和MCV系统,效果非常好!有一件事我有点困惑。它不是特定于代码的东西,而是更多关于逻辑的东西。简而言之:
- 控制器是从URL获取的
- 路由器调度控制器类并实例化它
- 被实例化的控制器类扩展了一个基控制器,并将使用相应的模型类
该模型类是静态的,不会被实例化。所以,假设我想创建一个新成员。从控制器类内部,我会有这样的东西:
Model::createMember($this->first_name, $this->last_name, $this->screen_name, $this->created_date);
然后,当然,在模型中,我会有一个在底层数据库中创建成员的方法,看起来像:
public function createMember($first_name, $last_name, $screen_name, $created_date) { blah blah blah }
这一切都很好,但在我看来,我应该能够从模型中直接访问控制器对象的属性,并避免传递所有这些参数。访问对象的属性对我来说似乎更OOP,所以这就是我想做的
问题是,我不能做
$controller_object = new Controller();
从模型类中引用控制器并访问其属性。
路由器上的控制器对象已经存在,所以创建一个新对象对我没有好处。我需要能够创建一个引用现有对象的变量。
现在我已经开始工作了,但我基本上把控制器对象的属性设置为全局的,然后可以用global关键字直接从模型类访问它们,但我真的不想这样做。
那么,我改进系统的想法是不是很糟糕,或者有没有一种方法可以引用现有的控制器对象,这样我就可以直接访问它的公共属性,而不必将参数从控制器传递到模型?
问题的直接答案是使用$this
,因为当你在控制器方法中时,它实际上代表了实例化的控制器,所以不是
Model::createMember($this->first_name, $this->last_name, $this->screen_name, $this->created_date);
你可以做这个
Model::createMember($this);
然后在模型内部,您可以访问控制器对象。
实际上,我不会这么做,因为模型实际上不应该依赖于控制器。
控制器的职责是解析传入的请求数据,创建模型并将请求数据传递到模型中。
实际上,在控制器中不需要具有first_name
、last_name
等属性。控制器可以只拥有一些带有传入数据的$data
数组,它不应该关心这些数据的实际内容。
模型的职责是验证数据(这也可以是一个单独的对象)并执行数据库操作或与数据相关的任何其他业务逻辑操作。
我也会避免对模型使用静态方法。代替
Model::createMember(...parameters...)
我会做
// $data is the request data parsed by controller
// controller knows how / where to get the data (from GET, POST, etc)
// but it doesn't care about the actual content
$model = Model($data)
...
if ($model->validate()) {
$model->save()
// show success message to the user
} else {
// show error message to the user
}