Как использовать PDO с внедрением зависимостей?

Мне трудно понять, как использовать внедрение зависимости. Я перечитал много вопросов / ответов здесь, но я не могу представить это с помощью кода, который я использую.

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 я расширяю класс модели, но я установил $db = static::getDB(); в каждой функции.

Я знаю, что внедрение зависимостей — это просто передача методов / переменных объекту, но я даже не уверен, что делаю это правильно.

Обновлено с дальнейшими мыслями:

Я думаю, что было бы лучше создать закрытую переменную, а в конструкторе мы бы просто вызвать 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();
}
}

Но будет ли он по-прежнему считаться внедрением зависимостей, поскольку я не вызываю класс непосредственно в конструкторе функции?

ВТОРОЕ ОБНОВЛЕНИЕ:
После прочтения нескольких руководств, и это страница что в итоге придало мне больше смысла, это то, что я придумал.

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();
}
}

Как это выглядит?

0

Решение

Я думаю, что вы не используете Dependency Injection, потому что вы на самом деле не предоставляете никаких зависимостей в вашу модель, вы генерируете их на конструкторе.

Чтобы предоставить зависимость, вы должны передать ее в качестве аргумента конструктору:

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

Таким образом, вы отделяете создание соединения от вашего класса и можете использовать преимущества внедрения зависимостей, такие как передача объекта Mock для тестирования вместо реальной вещи.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]