php mvc 调用,php – 在MVC应用程序中正确地从Model调用数据库?

Warning:

The information in this posts is extremely outdated. It represents my understanding of MVC pattern as it was more then 2 years ago. It will be updated when I get round to it. Probably this month (2013.09).

模型本身不应该包含任何SQL.永远.这意味着只包含域业务逻辑.

我建议的方法是把不是严格的“业务逻辑”的责任分成另外两套其他的组合:Domain Objects和Data Mappers.

例如,如果您正在制作博客,则模型不会被发布.相反,该模型最有可能是博客,并且该模型将处理多个域对象:Post,Comment,User和其他对象的多个实例.

在您的模型中,域对象不应该知道如何将自己存储在数据库中.或者甚至意识到任何形式的存储的存在.这是Data Mappers的责任.所有你应该在模型中做的是调用$mapper-> store($comment);.数据映射器应该知道如何存储一个特定类型的域对象,并且赢取哪个表放置信息(通常单个域对象的存储实际上会影响多个表).

一些代码

(仅文件相关的片段):

>我假设你知道如何写一个好的构造函数..如果你有疑问,请阅读this article

没有什么是命名的例子,但它应该是

>以示例中的_开头的任何东西都被保护

来自/application/bootstrap.php

/* --- snip --- */

$connection = new PDO( 'sqlite::memory:' );

$model_factory = new ModelFactory( $connection );

$controller = new SomeController( $request , $model_factory );

/* --- snip --- */

$controller->{$action}();

/* --- snip --- */

>控制器不需要知道数据库连接.

>如果要更改整个应用程序的数据库连接,则需要更改单行

>更改模型的方式,创建不同的类,实现与ModelFactory相同的界面

来自/framework/classes/ModelFactory.php

/* --- snip --- */

class ModelFactory implements ModelBuilderInterface

{

/* --- snip --- */

protected function _prepare()

{

if ( $this->_object_factory === null )

{

$this->_object_factory = new DomainObjectFactory;

}

if ( $this->_mapper_factory === null )

{

$this->_mapper_factory = new DataMapperFactory( $this->_connection );

}

}

public function build( $name )

{

$this->_prepare();

return new {$name}( $this->_object_mapper , $this->_data_mapper );

}

/* --- snip --- */

}

>只有数据映射器才会使用数据库,只有映射器工厂需要连接

> Model的所有依赖项都注入到构造函数中

>应用程序中的每个DataMapper实例都使用相同的DB连接,不需要Global State (video).

文件/application/controllers/SomeController.php

/* --- snip --- */

public function get_foobar()

{

$factory = $this->_model_factory;

$view = $this->_view;

$foo = $factory->build( 'FooModel' );

$bar = $factory->build( 'BarModel' );

$bar->set_language( $this->_request->get('lang') );

$view->bind( 'ergo' , $foo );

/* --- snip --- */

}

/* --- snip --- */

控制器不知道模型创建细节

控制器只负责接线和更改元件的状态

文件/application/models/FooModel.php

/* --- snip --- */

public function find_something( $param , $filter )

{

$something = $this->_object_factory('FooBar');

$mapper = $this->_mapper_factory('FooMapper');

$something->set_type( $param );

$mapper->use_filter( $filter )->fetch( $something );

return $something;

}

/* --- snip --- */

>域对象负责验证给定的参数

>视图接收并决定如何呈现

> mapper将对象放入存储器中(它不一定是DB ..它可以从一些文件或外部REST API中获得)所需的所有信息

我希望这将有助于您了解数据库逻辑与业务逻辑之间的分离(实际上也是演示逻辑)

很少的笔记

模型不应该扩展数据库或ORM,因为模型不是它们的一部分.通过扩展一个类,你声明它具有超类的所有特性,但有少许例外.

class Duck extends Bird{}

class ForestDuck extends Duck{}

// this is ok

class Table extends Database{}

class Person extends Table{}

// this is kinda stupid and a bit insulting

除了明显的逻辑问题,如果您的模型与底层数据库紧密结合,它使得代码非常难以测试(谈论Unit Testing (video)).

我个人认为,ORM是无用的,在大型项目中 – 甚至是有害的.问题起因于ORM正试图跨接两种完全不同的方式来解决问题:OOP和SQL.

如果您使用ORM启动项目,那么在短暂的学习曲线之后,您可以很快地编写简单的查询.但是当您开始打击ORM的限制和问题时,您已经完全投入使用ORM(即使是新人也被雇用,他们真的擅长您的选择,但是在纯SQL中吸引人).您最终会遇到每个新的DB相关问题需要越来越多的时间来解决的情况.如果您已经使用基于ActiveRecord模式的ORM,那么问题会直接影响到您的模型.

Uncle Bob称这是“技术债务”.

几本书

与主题松散相关

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值