如何将 PDO 与依赖注入一起使用?
How to use PDO with dependency injection?
我很难理解如何使用依赖注入。我在这里阅读了很多 questions/answers 但我无法用我正在使用的代码来描绘它。
Model.php
abstract class Model {
protected static function getDB() {
static $db = null;
if ($db === null) {
$db = new PDO('mysql:host=host;dbname=dbname;charset=utf8', 'dbuser', 'password');
}
return $db;
}
}
model.php 只包含那个函数,我想从设置和静态调用中移开它。
User.php
class User extends Model {
/*
* Selects all of the user information
*/
public function getUser($id){
$db = static::getDB();
$sth = $db->prepare('SELECT * FROM user WHERE id = :id');
$sth->bindValue(':id', $id, PDO::PARAM_INT);
$sth->execute();
return $sth->fetch();
}
/*
* Selects all of the user posts
*/
public function getUserPosts($id){
$db = static::getDB();
$sth = $db->prepare('SELECT * FROM user_posts WHERE user_id = :id');
$sth->bindValue(':id', $id, PDO::PARAM_INT);
$sth->execute();
return $sth->fetch();
}
}
在 user.php 中,我扩展了模型 class,但我在每个函数中都设置了 $db = static::getDB();
。
我知道依赖注入几乎只是将 methods/variables 传递给一个对象,但我什至不确定我是否做对了。
更新了进一步的想法:
我认为创建一个私有变量会更好,在构造函数中我们只需要像这样调用 getDB()
:
class User extends Model {
protected $db;
public function __construct(){
$this->db = getDB();
}
/*
* example usage
*/
public function getUser($id){
$sth = $this->db->prepare('SELECT * FROM user WHERE id = :id');
$sth->bindValue(':id', $id, PDO::PARAM_INT);
$sth->execute();
return $sth->fetch();
}
}
但是它仍然算作依赖注入,因为我没有在函数构造函数中直接调用 class 吗?
第二次更新:
在阅读了多个指南之后,这个 page 最终变得更有意义,这就是我想出的。
model.php
abstract class Model {
protected $db = null;
public function __construct(){
if($this->db === null){
try {
$this->db = new PDO('mysql:host=' . Config::DB_HOST . ';dbname=' . Config::DB_NAME . '; charset=utf8', Config::DB_USER, Config::DB_PASSWORD);
$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
}
return $this->db;
}
}
User.php
class User extends Model {
protected $db;
public function __construct(Model $db){
$this->db = $db;
}
/*
* example usage
*/
public function getUser($id){
$sth = $this->db->prepare('SELECT * FROM user WHERE id = :id');
$sth->bindValue(':id', $id, PDO::PARAM_INT);
$sth->execute();
return $sth->fetch();
}
}
看起来怎么样?
我认为您没有使用依赖注入,因为您实际上并没有向模型提供任何依赖项,而是在构造函数上生成它们。
为了提供依赖项,您应该将其作为参数传递给构造函数:
public function __construct($db){
$this->db = $db;
}
通过这种方式,您可以将连接的创建与 Class 分离,并且可以利用依赖注入的优势,例如传递 Mock 对象而不是实际对象进行测试。
我很难理解如何使用依赖注入。我在这里阅读了很多 questions/answers 但我无法用我正在使用的代码来描绘它。
Model.php
abstract class Model {
protected static function getDB() {
static $db = null;
if ($db === null) {
$db = new PDO('mysql:host=host;dbname=dbname;charset=utf8', 'dbuser', 'password');
}
return $db;
}
}
model.php 只包含那个函数,我想从设置和静态调用中移开它。
User.php
class User extends Model {
/*
* Selects all of the user information
*/
public function getUser($id){
$db = static::getDB();
$sth = $db->prepare('SELECT * FROM user WHERE id = :id');
$sth->bindValue(':id', $id, PDO::PARAM_INT);
$sth->execute();
return $sth->fetch();
}
/*
* Selects all of the user posts
*/
public function getUserPosts($id){
$db = static::getDB();
$sth = $db->prepare('SELECT * FROM user_posts WHERE user_id = :id');
$sth->bindValue(':id', $id, PDO::PARAM_INT);
$sth->execute();
return $sth->fetch();
}
}
在 user.php 中,我扩展了模型 class,但我在每个函数中都设置了 $db = static::getDB();
。
我知道依赖注入几乎只是将 methods/variables 传递给一个对象,但我什至不确定我是否做对了。
更新了进一步的想法:
我认为创建一个私有变量会更好,在构造函数中我们只需要像这样调用 getDB()
:
class User extends Model {
protected $db;
public function __construct(){
$this->db = getDB();
}
/*
* example usage
*/
public function getUser($id){
$sth = $this->db->prepare('SELECT * FROM user WHERE id = :id');
$sth->bindValue(':id', $id, PDO::PARAM_INT);
$sth->execute();
return $sth->fetch();
}
}
但是它仍然算作依赖注入,因为我没有在函数构造函数中直接调用 class 吗?
第二次更新: 在阅读了多个指南之后,这个 page 最终变得更有意义,这就是我想出的。
model.php
abstract class Model {
protected $db = null;
public function __construct(){
if($this->db === null){
try {
$this->db = new PDO('mysql:host=' . Config::DB_HOST . ';dbname=' . Config::DB_NAME . '; charset=utf8', Config::DB_USER, Config::DB_PASSWORD);
$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
}
return $this->db;
}
}
User.php
class User extends Model {
protected $db;
public function __construct(Model $db){
$this->db = $db;
}
/*
* example usage
*/
public function getUser($id){
$sth = $this->db->prepare('SELECT * FROM user WHERE id = :id');
$sth->bindValue(':id', $id, PDO::PARAM_INT);
$sth->execute();
return $sth->fetch();
}
}
看起来怎么样?
我认为您没有使用依赖注入,因为您实际上并没有向模型提供任何依赖项,而是在构造函数上生成它们。
为了提供依赖项,您应该将其作为参数传递给构造函数:
public function __construct($db){
$this->db = $db;
}
通过这种方式,您可以将连接的创建与 Class 分离,并且可以利用依赖注入的优势,例如传递 Mock 对象而不是实际对象进行测试。