dongyuqi3808 2017-09-13 21:39
浏览 55
已采纳

如何使用PDO与依赖注入?

I'm having a hard time understanding how to use dependency injection. I've read over a lot of questions/answers here but I can't picture it with the code I'm using.

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

The model.php just contains that function, which I want to move away from setting and calling it statically.

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

In the user.php I'm extending the model class, but I have set the $db = static::getDB(); in every single function.

I know that dependency injection is pretty much just passing the methods/variables to an object but I'm not even sure I'm doing this right.

Updated with further thoughts:

I'm thinking it would be better to create a private variable, and in the constructor we'd just call the getDB() like so:

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

But would it still count as dependency injection as I'm not calling the class directly in the function constructor?

SECOND UPDATE: After reading multiple guides, and this page which wound up making a lot more sense, this is what I came up with.

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

How does that look?

  • 写回答

1条回答 默认 最新

  • douyinghuo8874 2017-09-13 22:48
    关注

    I think that you are not using Dependency Injection because you are not actually supplying any dependencies into your Model, you are generating them on the constructor.

    In order to supply the dependency you should pass it as an argument to the constructor:

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

    This way you decouple the creation of the connection from your Class and you can use the benefits of Dependency Injection, like passing a Mock object for testing instead of the actual thing.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
  • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
  • ¥16 mybatis的代理对象无法通过@Autowired装填
  • ¥15 可见光定位matlab仿真
  • ¥15 arduino 四自由度机械臂
  • ¥15 wordpress 产品图片 GIF 没法显示
  • ¥15 求三国群英传pl国战时间的修改方法
  • ¥15 matlab代码代写,需写出详细代码,代价私
  • ¥15 ROS系统搭建请教(跨境电商用途)
  • ¥15 AIC3204的示例代码有吗,想用AIC3204测量血氧,找不到相关的代码。