我想为我的PHP应用程序构建一个模型类。它将具有根据方法的参数从数据库中选择/更新/插入/删除特定数据的方法。我只想使用准备好的陈述。
以下是该类应该是什么样的概述:
class Database {
private $_db;
// Stores a PDO object (the connection with the database) within the $_db property
public function __construct($host, $user, $password) {...}
public function select() {...}
public function update() {...}
public function insert() {...}
public function delete() {...}
}
问题在于我真的不知道该怎么做。让我们说我想从表格中选择所有内容" farm"动物是狗的地方。该语句的语法如下:
$animal = 'dog';
$query = $this->_db->prepare('SELECT * FROM farm WHERE animal = :animal');
$query->execute(array(':animal' => $animal));
$result_set = $query->fetchAll();
在类方法中实现这非常复杂。正如您所看到的,我调用了execute()
方法,但我事先并不知道是否会使用WHERE
子句!
更糟糕的是:如果我稍后想要使用LIMIT x, y
条款,那该怎么办呢?
我应该询问哪些参数以及如何对待它们?我是否应该简单地要求参数为一个查询+多个将传递给execute()
方法的变量?
这些类型的方法对我想做的事情是否合理?也许我应该为应用程序将执行的每个MySQL查询使用专用方法,但这非常复杂,因为它是一个大型数据库和一个大型应用程序。
你们有什么想法?
提前致谢:P
答案 0 :(得分:3)
你的API对我来说看起来毫无用处,因为我认为它只是PDO的一个包装器。像这样包装PDO你会得到什么?
相反,让对象实际代表事物可能更有意义,例如:
namespace Project\Storage\Database;
class Farm
{
private $pdo;
public function __construct(\PDO $pdo)
{
$this->pdo = $pdo;
}
public function getAnimalsByType(string $animalType): AnimalCollection
{
$stmt = $this->pdo->prepare('SELECT * FROM farm WHERE animal = :animal');
$stmt->execute([
'animal' => $animalType,
]);
// alternatively use a factory to build this to prevent tight coupling
return new AnimalCollection($stmt->fetchAll());
}
}
旁注:忘记PHP中的MVC(它甚至不可能)。只关注更重要的separation of concerns。
答案 1 :(得分:1)
也许我应该为应用程序的每个MySQL查询提供专用方法 执行,但这很复杂,因为它是一个大数据库和 一个很大的应用程序。
是的,这是组织数据库访问的简便方法。
但你不应该将所有这些都放在同一个班级。您应该按照其域名分隔您的课程。
class animalRepository {
// ...
public function getAnimalByName($animal){
$query = $this->_db->prepare('SELECT * FROM farm WHERE animal = :animal');
$query->execute(array(':animal' => $animal));
$result_set = $query->fetchAll();
// ...
}
}
为了更清楚地沟通,您可以调用这些类存储库,因为它们存储特定域的数据。
另一个常见名称是mappers,因为它们将数据映射到您的对象。
答案 2 :(得分:1)
非常自以为是的答案。无论如何:
PDO的准备语句比创建它们更有能力并且在它们上面调用execute
。通常如何构建查询然后绑定值:
$querystring = 'SELECT * FROM farm';
$args = array();
if($animal != '') {
$querystring .= 'WHERE animal = :animal';
$args[':animal'] = $animal;
}
$query = $this->_db->prepare($querystring);
$result = $query->execute($args)
if($result !== false) {
// fetch ...
} else {
// error output / return val
}
这是一般的想法。根据您的输入参数,您可以构建查询。它可能会变得比那更复杂,例如填充$where = array()
然后你添加到$where[] = ...
你的where条件,最后你只需将它们与sql AND
一起加入:
$this->_db->prepare($querystring.
( count($where) > 0 // the > 0 is redundant btw
? 'WHERE '.implode('AND',$where)
: '' )
);
你可能对连接表,select语句等有类似的东西。它会变得非常复杂。将这种方法与在Philipp的答案/方法中合理分离的方法混合可能是明智的。