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 足以保持书籍和流派的关系。
学习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 足以保持书籍和流派的关系。