学习Zend3框架。在一个示例Zend3项目上工作,我必须创建一个Model子类型。
我有以下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,
];
}
}
现在我必须创建:
被称为“Thriller”的子类型“Book”,继承自“Book”并具有名为“excitement_factor”的附加属性
而:
它在数据库和模型中正确反映了这种关系,我应该:
最后确保数据库完整性:
实现足够的表模型函数来检索,保存和删除“惊悚片”,对所有查询使用ORM样式
我怎样才能做到这一点?
应该让Thriller使用新领域扩展Book类吗?我如何在Zend3中执行此操作?基础表怎么样? Zend会为Thriller创建新表吗?我要调整哪些文件?
使用ORM Style方法是指fetchAll(),fetchOneBy()等?
谢谢,
更新1:
我的书表如下:
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))
创建第二个表格Thriller:
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');
}
我如何添加现在的惊悚片?
public function addThrillerAction()
{
// ???
}
“颤栗”必须是书籍对象吗?也许它可以是书籍对象的“类型”。在这种方法中,book对象具有属性“genres”,当然还有“addGenre / removeGenre / hasGenre / getGenres”方法。我的意思是每本书都有不止一种类型。您还可以将所有类型保留在表格中,获取它们并填充表单。顺便说一句,你可以对它们运行查询。数据透视表足以保持书籍和流派的关系。