使用带有PDO的数据库类

时间:2015-07-21 20:51:36

标签: php mysql pdo database-connection

经典的第一个班轮 - 在SO上看到了类似的问题,但没有一个能真正帮助我理解我所处的十字路口。

代码之前的一点背景 - 我不是PHP或PDO的新手(虽然也不是专家),但我是面向对象PHP的完全新手,我正试图在何时使用类和何时获得平衡这可能是矫枉过正的。

我希望答案分为两部分。首先,最好在使用PDO时创建包装器数据库类 - 用于连接,基本查询等。

其次,如果没有 - 是否有更好的方法来加快查询编写速度?

编辑虽然我在质疑下面的代码,但实际上我总体上质疑PDO包装类方法 - 所以下面的类可能比这要大得多,但有没有需要/好处?< / p>

请参阅以下代码; 注意:通过config.php中的spl_autoload_register()调用类文件

class_database.php

class Database
{
    private $conn;

    public function __construct() {
        $this->openConnection();
    }

    public function openConnection() {
        try {
            $this->conn = new PDO('mysql:host=' . DB_SERVER . '; dbname=' . DB_NAME, DB_USER, DB_PASS);
            $this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch (PDOException $e) {
            echo 'There was an error connecting to the database, Error: ' . $e->getMessage();
            die();
        }
    }

    public function getAll($sql, array $params) {
        $stmt = $this->conn->prepare($sql);
        $stmt->execute($params);
        return $stmt->fetch(PDO::FETCH_ASSOC);
    }
}

generic_file.php

require_once '../includes/config.php';
$dbh = new Database();

$sql = ("SELECT * FROM users where id = :id and username = :username");
$id = 1;
$username = 'craig';
$params = array(':id' => $id,
                ':username' => $username);
$row = $dbh->getAll($sql, $params);
var_dump($row);

现在,对我而言,这似乎毫无意义。单独使用PDO而不是包装类,这个查询就像编写一样简单。除此之外 - 如果我想使用不同的fetch方法 - 我必须在类中编写更多方法。 此外,以前我使用了一个简单的函数来实例化并返回一个新的PDO对象,只是包含该文件并将一个变量赋值给函数返回很简单 - 再次我认为类方法是过度的。

另外,使用上面的代码,并通过在类中执行此操作,我不会失去“准备”语句的好处,因为我必须每次都传递sql语句,甚至只是为了更改变量同样的声明?

但是,我在网上找到了很多例子,尤其是我目前使用的Lynda.com的数据库包装类。最重要的是 - 我不是专家,因此我认为矫枉过正可能是最佳实践并且强烈推荐,因此请各位专家帮助我!

所以......回到我的问题 - 在使用PDO时是否有充分的理由使用这样的课程? 如果没有,是否有其他DRY方法,其他人使用这种方法来最小化使用PDO查询所需的代码行?

提前致谢。

1 个答案:

答案 0 :(得分:1)

我一次有同样的问题。

抽象数据库的好处是可以确保所有连接都正确无误,如果您确实需要更改数据库类型,则只需要更改代码的一个位置。它还可以更容易地检查发​​出的查询,因为您知道如果您在类中回显并退出,则所有查询都将被检查。

我解决它的方法是创建一个类,其中构造函数建立连接并将其分配给私有变量,同时也在数据库中设置表。 最好的方法是使用一些公共函数来创建,检索,更新和删除。有时称为CRUD。 对于每个函数,唯一和第一个参数是数组。为了创建它,需要数组并使用它创建一个准备好的语句然后执行它。 它与其他人做了非常类似的事情,但是对于检索数组是匹配的内容,对于更新,它采用以id结尾的内容并将其余部分设置为更新id =提供的位置,并且对于删除它将删除所有的keys =表中的值。

编辑: 这是我在课堂上放的删除功能。如果参数的值之一是数组,它将准备语句并循环通过它。这仅适用于一个变量。您也可以使用它来传递数组,其中数值索引的值是您想要插入的数组,但这不是我设置代码的方式。

public function delete($info) {
    $dbh = $this->dbh;

    if (isset($info['submit_action'])) unset($info['submit_action']);
    $where = array();
    foreach (array_keys($info) as $name) {
        $where[] .= "$name = :$name";
    }
    //echo "DELETE FROM {$this->table_name} WHERE " . implode(" AND ", $where) . ";"; exit;
    $data = $dbh->prepare("DELETE FROM {$this->table_name} WHERE " . implode(" AND ", $where) . ";");
    foreach ($info as $name => $value) {
        if ($array_value == $name) $data->bindParam(":$name", $array_info);
        else $data->bindValue(":$name", trim($value));
    }

    foreach ($info as $name => $value) if (is_array($value)) { $array_value = $name; break; }
    if (isset($array_value)) {

        foreach ($info[$array_value] as $array_info) {
            try {
                $data->execute();
            }
            catch (PDOException $e) {
                if (!is_null($this->error_msg))
                    handle_error($this->error_msg, $e->getMessage());
                else
                handle_error("There was a problem removing the {$this->subject}.", $e->getMessage());
            }
        }

    } else {
        try {
            $data->execute();
        }
        catch (PDOException $e) {
            handle_error(/*public error msg - could set this anyway you want*/, $e->getMessage());
        }
    }

    // Send success msg
}