PHP:重构为OO - 如何建模连接

Ste*_*ane 5 php oop model-view-controller join

假设我有两种型号:

class Book
{
    public $book_id;
    public $book_author_id;
    public $title;
}

class Author
{
    public $author_id;
    public $author_name;
}
Run Code Online (Sandbox Code Playgroud)

我习惯写这样的东西:

$DB->query("SELECT book_id, title, author_name 
            FROM book 
            LEFT JOIN author 
                ON book_author_id = author_id
           ");
Run Code Online (Sandbox Code Playgroud)

让我们假设,我对这个关联的单独查询不感兴趣.我该怎么办?以下是我听过的一些事情:

  • 创建JOIN的MySQL视图
  • 创建VIEW的模型类

我正在处理的应用程序涉及许多表,并且在过程代码中进行了高度优化(例如,几乎没有任何SELECT*).我正在重构以使其更易于维护(我也是最初的创建者),但我想在不需要破坏文件结构和数据库调用的情况下灵活地使用连接.

我可能相关的问题与包括其他模型有关:

class Author
{
    public $author_id;
    public $author_name;

    /* @var Book */ //<--don't really fully understand this but I've seen something like it somewhere
    public (array) $authors_books;
}
Run Code Online (Sandbox Code Playgroud)

我仍然在寻找答案,但如果你能以我的方式发送链接,那将不胜感激.

ter*_*ško 3

您所说的“模型”实际上是域对象。他们应该负责处理领域业务逻辑,与存储无关。

与存储相关的逻辑和交互应该由单独的对象组处理。最明智的解决方案之一是使用数据映射器。每个映射器可以处理多个表和复杂的SQL。

至于您的查询,此类查询的结果将包含适合传递给域对象集合的信息。

顺便说一句,该查询毫无用处。您忘记了每本书可以有多个作者。以这本书为例——它有 4 位不同的作者。要使此查询有用,您应该GROUP_CONCAT()基于author_id或进行操作book_id

执行此类JOIN语句时,数据库响应很可能是一个集合:

$mapper = $factory->buildMapper('BookCollection');
$collection = $factory->buildCollection('Book');

$collection->setSomeCondition('foobar');
$mapper->fetch( $collection );
foreach ( $collection as $item )
{
    $item->setSomething('marker');
}
$mapper->store( $collection );
Run Code Online (Sandbox Code Playgroud)

PS您的代码示例似乎正在泄漏抽象。让其他结构直接访问对象的变量是一种不好的做法。

PPS看来你对MVC模型部分的理解与我的看法有很大不同。