过去几天,我广泛阅读OOP和MVC在PHP书籍和网页,这样我可以成为一个更好的程序员。 我已经降临在我的MVC的理解有点问题:
我在哪里放mysql_query
?
我应该把它的控制器,并呼吁返回根据所提供的查询数据模型的方法? 或者我应该把它放在模型本身? 都是的我提供垃圾总量的选项?
过去几天,我广泛阅读OOP和MVC在PHP书籍和网页,这样我可以成为一个更好的程序员。 我已经降临在我的MVC的理解有点问题:
我在哪里放mysql_query
?
我应该把它的控制器,并呼吁返回根据所提供的查询数据模型的方法? 或者我应该把它放在模型本身? 都是的我提供垃圾总量的选项?
你可以列出你读书籍,因为大部分(如果不是全部)的PHP书籍,对MVC其触摸,都是错误的。
如果你想成为一个更好的开发者,我会建议你与Marting福勒的文章开始- GUI架构 。 其次是来自同一作者的书- “企业应用架构模式” 。 那么下一步将是您研究SOLID原则 ,并了解如何编写下面的代码得墨忒耳定律 。 这应包括基础=]
并不是的。 至少不是传统的MVC,因为它是对Smalltalk的定义 。
相反,在PHP中你有4个旨在为同一目标等图案:MVC模型2,MVP,MVVM和HMVC。 同样,我懒得写的差异更多的时间,所以我就链接到一个旧的评论我的。
你必须了解的第一件事是,在MVC模式是不是一个类或对象。 它是包含类大量的层。 基本上模型层是所有的层相结合的(尽管,所述第二层有应称为“域对象层”,因为它包含“域模型对象”)。 如果你愿意读什么是包含在模型层的每个部分简要总结,你可以尝试阅读这个老评论 (跳到“侧面说明”部分)。
图片取自服务层文章Fowler的网站。
控制器在MVC(我要说说Model2的实施此处)一个主要职责:
从模型层(服务或域对象)结构,其改变所述结构的状态执行命令。
它通常有一个次要责任:绑定(或者通过)从模型层结构的视图,但它变成一个可疑的做法,如果你遵循SRP
存储和检索信息在数据源层的处理,通常为实现DataMapper的 (不奥姆斯,其中滥用这个名字混淆)。
下面是如何简化使用它会是什么样子:
$mapper = $this->mapperFactory->build(Model\Mappers\User::class);
$user = $this->entityFactory->build(Model\Entities\User::class);
$user->setId(42);
$mapper->fetch($user);
if ($user->isBanned() && $user->hasBannExpired()){
$user->setStatus(Model\Mappers\User::STATUS_ACTIVE);
}
$mapper->store($user);
正如你看到的,在任何时候域对象是否意识到,这是存储从它的信息。 而且,无论是它的情况下你把数据在哪里。 它可以存储在MySQL或PostgreSQL或一些NoSQL数据库。 或者,也许推到远程REST API。 或者,也许是映射器用于测试的模拟。 所有你需要做的,是取代映射,是提供这种方法具有不同的工厂。
模型和实体类表示数据和应用程序的逻辑,是许多电话业务逻辑。 通常情况下,它的职责是:
这里是MVC序列图,显示一个http请求时的流动:
在这种情况下,模型是实现realted访问数据库的代码的最佳场所。
该模型包含的域对象或代表应用程序的状态数据结构。 [维基百科] 。 因此,该模型将是使数据库调用的地方。
在“经典”(缺乏一个更好的词大气压)MVC模式的观点会得到从模型的当前状态。
不要说,该模型是用于访问数据库犯这样的错误。 这不仅仅是访问数据库的更多。
首先,不使用mysql_query()
和家庭; 他们被弃用,因此,考虑也学习PDO和/或mysqli的。
该模型需要照顾的数据处理; 将其提供给通过它检索和/或存储信息的控制器的接口。 因此,这将是一个主要的地方,数据库操作发生。
更新
要回答由OP在评论中问了一个问题:“整个数据库或为每个表/行动的典范一个通用模型”
模型是指抽象出单独的表(虽然有模型,专门处理单个表); 例如,而不是要求所有的文章,然后查询为作者的用户名,你就会有这样一个功能:
function getArticles()
{
// query article table and join with user table to get username
}
有多少车型将创建在很大程度上取决于项目有多大,以及如何相互关联的数据。 如果你能识别数据的独立团体,很可能你会为每个组创建一个模型; 但是这是没有硬的快速规则。
数据操作可以是同一模型的一部分,除非你想只读和只写模型之间的明确分离(我不知道的,值得这样的情况,但谁知道)。
再进一步,你的模型不应包含数据库访问代码。 这属于模型/视图/控制器之外的另一个层:这就是所谓的持久层 ,其可以使用一个来实现对象关系映射器 ,如流行的学说2为PHP。
这样一来,你从来没有接触任何(我的)SQL代码。 持久层负责为你处理。 我真的建议你看看一个学说的教程,这是创建您的应用程序一个真正专业的方式。
相反,从数据库加载原始数据的工作,将创建一个保存数据的对象,以及与之相关联的行为。
例如,你可能有一个User
类,如:
class User
{
protected $id;
protected $name;
protected $privileges;
public function setName($name) { ... }
public function getName() { ... }
public function addPrivilege(Privilege $privilege) { ... }
public function getPrivileges() { ... }
}
您控制器将只与物体相互作用:
class UserController
{
public function testAction()
{
// ...
$user = $em->getRepository('User')->find(123); // load User with id 123
$user->setName('John'); // work with your objects,
echo $user->getName(); // and don't worry about the db!
$em->flush(); // persist your changes
}
}
在幕后,ORM需要的所有发出的低层次的工作照顾SELECT
查询,实例化你的对象,检测修改你的对象,并发出必要的UPDATE
语句!