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

前端之家收集整理的这篇文章主要介绍了php – 在MVC应用程序中正确地从Model调用数据库?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在建立一个用于学习/实验和小项目目的的小型MVC框架.我需要找出Model的内部基础知识,因为完整的MVC框架和ORM对于几个数据库调用来说是过分的.
Class Model
{
}

使用一个空类,我必须调用一个新的PDO对象进行数据库调用

什么叫调用查询看起来像模型?

另外,在哪里可以找到一个初学者的web / book资源到MVC(有很多示例代码)?我听说过很多术语,如业务逻辑和数据库逻辑.我记得阅读某个地方你应该分离业务逻辑和数据库逻辑.我可以理解这个概念,我只是想知道它的外观或代码本身的含义.我很困惑如何将业务逻辑和数据库逻辑分开,但仍然在模型中.

我主要寻找代码/逻辑示例作为答案,除了后面的段落.

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 ObjectsData 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称这是“技术债务”.

几本书

主题松散相关

> Patterns of Enterprise Application Architecture
> Agile Software Development,Principles,Patterns,and Practices
> SQL Antipatterns: Avoiding the Pitfalls of Database Programming
> PHP Object-Oriented Solutions
> PHP in Action

猜你在找的PHP相关文章