我最近完成了我的第一个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连接?
提前致谢。