我想创建一个PHP类来包含某种数据(带有“标题”和“文本”的文章)。该类应该用于不同的目的:
创建新条目:显示一个空的“标题”和“文字”的表单 输入字段和提交按钮以将数据添加到数据库(之后 验证)
编辑现有条目(将ID传递给构造函数):show a 带有“标题”和“文本”输入字段的表单,其中填充了检索到的数据 从DB和一个提交按钮添加数据到数据库(之后 验证)
查看现有条目(将ID传递给构造函数):show 填写了不可编辑的“标题”和“文本”字段(即“h1”和“p”) 从数据库中检索数据
删除现有条目(将ID传递给构造函数):show 填写了不可编辑的“标题”和“文本”字段(即“h1”和“p”) 从数据库中检索数据和从中删除数据的提交按钮 数据库
这应该是一种非常常见的情况,但我没有找到任何设计模式来执行它。 你有什么建议吗?提前谢谢。
答案 0 :(得分:1)
由于所有这些CRUD“操作”都属于相同的责任(它们进行抽象表访问),因此不需要为每个操作实现分离的类。您将实现一个抽象单个操作的方法,该方法与您正在使用的表相关。你可以这样做,如:
class ArticleMapper
{
protected $pdo;
protected $table = 'some_table';
public function __construct(PDO $pdo)
{
$this->pdo = $pdo;
}
/**
* @return boolean Depending on success
*/
public function insert($id, $title, $text)
{
$query = sprintf('INSERT INTO `table` (`id`, `title`, `text`) VALUES (:id, :title, :text)', $this->table);
$stmt = $this->pdo->prepare($query);
return $stmt->execute(array(
':title' => $title,
':text' => $text,
':id' => $id,
));
}
public function fetchById($id)
{
$query = sprintf('SELECT * FROM `%s` WHERE `id` =:id');
$stmt = $this->pdo->prepare($query);
$stmt->execute(array(
':id' => $id
));
return $stmt->fetch();
}
// ... The rest for deleteById() and updateById()
}
好吧,如果它们不明显,那么倾听它们是有道理的:
这意味着您的应用程序逻辑(执行某些计算)将完全不知道数据来自何处。这使您易于维护和测试。这符合单一责任原则
虽然ORM,ActiveRecords,Query Builders确实需要额外的内存(顺便说一下,对于每个HTTP请求,而且只是看看,在他们的类中 - 它们通常都是如此之大),而DataMappers却没有。您只需为您将要使用的数据库供应商编写代码。
例如,让我们假设您现在不确定,将来是否要切换到其他数据库供应商。使用DataMappers时,您所要做的就是将它的实例注入需要它的类中。
class Foo
{
public function __construct(MapperInterface $mapper)
{
$this->mapper = $mapper;
}
public function doSomeComputationsWithId($id)
{
$data = $this->mapper->fetchById($id);
// .. do computations here
return $result;
}
}
$mapper = new Article_MySQL_Mapper($pdo);
// or
$mapper = new Article_MongoDB_Mapper($mongoInstance);
$foo = new Foo($mapper);
print_r($foo->doSomeComputationsWithId($_GET['id']));
答案 1 :(得分:0)
大多数PHP MVC都包含针对这类问题的良好设计模式。查看类似的框架:
如果你想保持简单,只为这个问题设计一个PHP类,你应该检查CRUD,ORM和ActiveRecord。以下链接可能会派上用场:PHP ActiveRecord