在OO PHP

时间:2015-11-06 14:00:43

标签: php mysql pdo

我最近完成了我的第一个OO PHP项目,现在开始我的第二个项目,我希望能够解决我对第一个方法的担忧。

我最关心的是我的数据库连接。

这是我在第一个项目中所做的......

database.class.php

class Database
{
    protected $db_host = 'localhost';
    protected $db_name = 'mydbname';
    protected $db_user = 'mydbuser';
    protected $db_pass = 'mydbpass';

    protected $dbh;

    public function __construct()
    {
        try {
            $dbh = new PDO('mysql:host=' . $this->db_host . ';dbname=' . $this->db_name, $this->db_user, $this->db_pass);
            $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch (PDOException $e) {
            echo $e->getMessage();
            die();
        }
        $this->dbh = $dbh;
    }

}

然后我为每个数据库表都有Dao类,它们有各自的CRUD方法。这些类中的每一个都扩展了我的数据库类,这意味着没有任何额外的代码,他们可以访问PDO连接。例如;

class UserDao extends Database
{
    public function __construct()
    {
        /* Would be called automatically, but here for clarity */
        parent::__construct();
    }

    public function addUser($username, $password, $friendly_name)
    {
        $stmt = $this->dbh->prepare("INSERT INTO users (username, password, friendly_name) VALUES (:username, :password, :friendly_name)");
        $encrypted = password_hash($password, PASSWORD_DEFAULT);
        $stmt->bindParam(':username', $username);
        $stmt->bindParam(':password', $encrypted);
        $stmt->bindParam(':friendly_name', $friendly_name);

        $stmt->execute();

    }

    public function checkUserCredentials($username, $password)
    {
        $stmt = $this->dbh->prepare("SELECT id, password FROM users where username = :username LIMIT 1");
        $stmt->bindParam(':username', $username);
        $stmt->execute();
        if ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
            if (password_verify($password, $row['password'])) {
                return $row['id'];
            }
            else {
                return false;
            }
        }
        return false;
    }

    public function getUserById($id)
    {
        try {
            $stmt = $this->dbh->prepare("SELECT username, friendly_name FROM users WHERE id = :id LIMIT 1");
            $stmt->bindParam(":id", $id);
            $stmt->execute();
            $user = $stmt->fetch(PDO::FETCH_ASSOC);
            return $user;
        } catch (PDOException $e) {
            echo $e->getMessage();
            exit;
        }
    }

}

我担心的是我已经在SO和Code Review上阅读了很多答案,并且似乎有很多人认为在课堂上包装PDO连接毫无意义。

但是 - 我确信这些开发人员不会在每次需要连接数据库时手动创建新的PDO并传递连接参数 - 因此,如何在不使用类的情况下实现DRY原则?

我假设的一种方法是在每个页面上包含的配置文件中的函数...

function dbh_connect() {
try {
    $dbh = new PDO('mysql:host=localhost;dbname=ward_stats', 'ward_stats_user', 'Mu9w!V5hhM');
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

} catch (PDOException $e) {
    print "Sorry, there was an error connecting to the database.<br>";
    die();
}
return $dbh;

}

然后,假设我将此连接传递给需要的类,使用依赖注入,我可以在另一个脚本中执行以下操作;

$dbh = dbh_connect();
$user = new UserDao($dbh);

这里有一个比另一个好吗?或者是否有更好的方法在面向对象的环境中处理PDO连接?

提前致谢。

0 个答案:

没有答案