Zend3 模型子类型

Zend3 Model subtype

学习Zend3框架。在我必须创建模型子类型的示例 Zend3 项目上工作。

我有以下 Book.php 型号:

<?php

namespace Products\Model;

class Book
{
    public $id;
    public $author;
    public $title;
    public $isbn;



    public function exchangeArray(array $data)
    {
        $this->id     = !empty($data['id']) ? $data['id'] : null;
        $this->author = !empty($data['author']) ? $data['author'] : null;
        $this->title  = !empty($data['title']) ? $data['title'] : null;
        $this->isbn  = !empty($data['isbn']) ? $data['isbn'] : null;
    }

    public function getArrayCopy()
    {
        return [
            'id'     => $this->id,
            'author' => $this->author,
            'title'  => $this->title,
            'isbn'  => $this->isbn,

        ];
    } 

}

现在我必须创建:

"Book" 的一个子类型,称为 "Thriller",继承自 "Book",并有一个额外的 属性,称为 "excitement_factor"

同时:

它在数据库和您的模型中正确反映了这种关系,我应该:

还要确保数据库的完整性,最后:

实施足够的 table 模型函数来检索、保存和删除 "thriller"s,对所有查询使用 ORM 样式

我该怎么做?

Thriller 应该用新领域扩展 Book class 吗?我如何在 Zend3 中执行此操作?底层的 table 呢? Zend 会为 Thriller 创建新的 table 吗?我必须调整哪些文件?

对于 ORM 样式方法,它意味着 fetchAll()、fetchOneBy() 等?

谢谢,

更新 1:

我的书table如下:

CREATE TABLE book (id INT AUTO_INCREMENT NOT NULL, author varchar(100) NOT NULL, title varchar(100) NOT NULL, isbn varchar(100) NOT NULL, type ENUM("Thriller") NOT NULL, PRIMARY KEY(id))

创作第二部table惊悚片:

CREATE TABLE thriller
(
    id INT NOT NULL,
    book INT NOT NULL,
    excitement_factor VARCHAR(100) NOT NULL,
    PRIMARY KEY(id),
    FOREIGN KEY(book) REFERENCES book(id)
)

两者都有 TableGateways。

型号如下:

cat Book.php 
<?php

namespace Products\Model;

class Book
{
    public $id;
    public $author;
    public $title;
    public $isbn;

    private $inputFilter;

    public function exchangeArray(array $data)
    {
        $this->id     = !empty($data['id']) ? $data['id'] : null;
        $this->author = !empty($data['author']) ? $data['author'] : null;
        $this->title  = !empty($data['title']) ? $data['title'] : null;
        $this->isbn  = !empty($data['isbn']) ? $data['isbn'] : null;
    }

    public function getArrayCopy()
    {
        return [
            'id'     => $this->id,
            'author' => $this->author,
            'title'  => $this->title,
            'isbn'  => $this->isbn,

        ];
    } 

}
cat BookTable.php 
<?php

namespace Products\Model;

use RuntimeException;
use Zend\Db\TableGateway\TableGatewayInterface;

class BookTable
{
    private $tableGateway;

    public function __construct(TableGatewayInterface $tableGateway)
    {
        $this->tableGateway = $tableGateway;
    }

    public function fetchAll()
    {
        return $this->tableGateway->select();
    }

    public function getBook($id)
    {
        $id = (int) $id;
        $rowset = $this->tableGateway->select(['id' => $id]);
        $row = $rowset->current();
        if (! $row) {
            throw new RuntimeException(sprintf(
                'Could not find row with identifier %d',
                $id
            ));
        }

        return $row;
    }

    public function saveBook(Book $book)
    {
        $data = [
            'author' => $book->author,
            'title'  => $book->title,
            'isbn'  => $book->isbn,

        ];

        $id = (int) $book->id;

        if ($id === 0) {
            $this->tableGateway->insert($data);
            return;
        }

        if (! $this->getBook($id)) {
            throw new RuntimeException(sprintf(
                'Cannot update book with identifier %d; does not exist',
                $id
            ));
        }

        $this->tableGateway->update($data, ['id' => $id]);
    }

    public function deleteBook($id)
    {
        $this->tableGateway->delete(['id' => (int) $id]);
    }
}

cat Thriller.php 
<?php

namespace Products\Model;

class Thriller
{
    public $id;
    public $book;
    public $excitement_factor;

    private $inputFilter;

    public function exchangeArray(array $data)
    {
        $this->tid     = !empty($data['id']) ? $data['id'] : null;
        $this->book = !empty($data['book']) ? $data['book'] : null;
        $this->excitement_factor = !empty($data['excitement_factor']) ? $data['excitement_factor'] : null;
    }

    public function getArrayCopy()
    {
        return [
            'id'     => $this->id,
            'book' => $this->book,
            'excitement_factor' => $this->excitement_factor,

        ];
    } 

}

cat ThrillerTable.php 
<?php

namespace Products\Model;

use RuntimeException;
use Zend\Db\TableGateway\TableGatewayInterface;

class ThrillerTable
{
    private $tableGateway;

    public function __construct(TableGatewayInterface $tableGateway)
    {
        $this->tableGateway = $tableGateway;
    }

    public function fetchAll()
    {
        return $this->tableGateway->select();
    }

    public function getThriller($id)
    {
        $id = (int) $id;
        $rowset = $this->tableGateway->select(['id' => $id]);
        $row = $rowset->current();
        if (! $row) {
            throw new RuntimeException(sprintf(
                'Could not find row with identifier %d',
                $id
            ));
        }

        return $row;
    }

    public function saveThriller(Thriller $thriller)
    {
        $data = [
            'book' => $thriller->book,
            'excitement_factor'  => $thriller->excitement_factor,


        ];

        $id = (int) $thriller->id;

        if ($id === 0) {
            $this->tableGateway->insert($data);
            return;
        }

        if (! $this->getThriller($id)) {
            throw new RuntimeException(sprintf(
                'Cannot update thriller with identifier %d; does not exist',
                $id
            ));
        }

        $this->tableGateway->update($data, ['id' => $id]);
    }

    public function deleteThriller($id)
    {
        $this->tableGateway->delete(['id' => (int) $id]);
    }
}

在我的控制器中添加 Book,我只是这样做:

public function addBookAction()
    {
        $form = new BookForm();
        $form->get('submit')->setValue('Add');

        $request = $this->getRequest();

        if (! $request->isPost()) {
            return ['form' => $form];
        }

        $bookForm = new BookForm();
        $form->setInputFilter($bookForm->getInputFilter());
        $form->setData($request->getPost());

        if (! $form->isValid()) {
            return ['form' => $form];
        }

        $bookModel = new Book();

        $bookModel->exchangeArray($form->getData());


        $this->book->saveBook($bookModel);
        return $this->redirect()->toRoute('product');
    }

现在如何添加Thriller?

public function addThrillerAction()
{
    // ???
}

"Thriller" 必须是书籍对象吗?也许它可以是 "genre" 的书籍对象。在这种方法中,书籍对象有一个 属性 作为 "genres",当然还有 "addGenre/removeGenre/hasGenre/getGenres" 方法。我的意思是每本书可以有不止一种类型。您还可以将所有流派保存在 table 中,获取它们并填充表格。顺便说一下,您可以 运行 查询它们。一个支点 table 足以保持书籍和流派的关系。