MVC / PDO:如何使用PDO编写的语句语法构建模型?

时间:2016-08-02 08:29:39

标签: php mysql oop

我想为我的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

3 个答案:

答案 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的答案/方法中合理分离的方法混合可能是明智的。