gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-10-31 22:41:24 25 4
gpt4 key购买 nike

我正在构建一个用于学习/实验和小型项目的小型 MVC 框架。我需要找出模型内部的基础知识,因为一个完整的 MVC 框架和 ORM 对几个数据库调用来说是多余的。

Class Model
{
}

使用一个空类,我必须在哪里调用 new PDO数据库调用的对象?

在模型内部调用查询会是什么样子?

另外,我在哪里可以找到初学者的 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).

Damn it! (2017.11).


Model本身不应包含 任何 SQL。曾经。它旨在仅包含域业务逻辑。

我建议的方法是将职责(并非严格意义上的“业务逻辑”)划分为另外两组结构: Domain ObjectsData Mappers .

例如,如果您正在制作博客,那么模型将不会是 Post。相反,模型很可能是 Blog ,并且该模型将处理多个 Domain Objects : Post、Comment、User 和其他对象的多个实例。

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

一些代码

(仅来自文件的相关片段):
  • 我假设您知道如何编写一个好的构造函数.. 如果您有疑问,请阅读 this article
  • 示例中没有命名空间,但它应该是
  • 任何以 _ 开头的内容例如是 protected

  • 来自 /application/bootstrap.php
    /* --- snip --- */

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

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

    /* --- snip --- */

    $controller->{$action}();

    /* --- snip --- */
  • Controller 不需要知道数据库连接。
  • 如果要更改整个应用程序的数据库连接,则需要更改单行
  • 要更改模型的制作方式,您可以创建实现与 ModelFactory 相同接口(interface)的不同类


  • 来自 /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 的所有依赖都注入(inject)到构造函数中
  • 应用程序中的每个 DataMapper 实例都使用相同的数据库连接,没有 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 --- */
  • Controller 不知道模型创建细节
  • Controller 只负责接线和改变元件状态


  • 文件 /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 --- */
  • 域对象负责验证给定的参数
  • View 接收并决定如何呈现它
  • 映射器获取对象并将所有必需的信息从存储中放入其中(它不必是 DB ..它可以从某个文件或外部 REST API 中获取)


  • 我希望这将帮助您理解 DB 逻辑和业务逻辑(实际上也是表示逻辑)之间的分离

    几个笔记

    模型永远不应该扩展数据库或 ORM,因为模型不是它们的子集。通过扩展一个类,您声明它具有父类(super class)的所有特征,但有少数异常(exception)。
    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 却一窍不通)。您最终会遇到每个与数据库相关的新问题都需要越来越多的时间来解决的情况。如果你一直在使用基于 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 - 在 MVC 应用程序中从 Model 正确调用数据库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5895805/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com