Search Posts

PHP Dependency Injection when multiple types of databases are used in the same class

how to – PHP Dependency Injection when multiple types of databases are used in the same class

I’m working on a very unorganized (no tests, logic mixed in everywhere) PHP application. I started reading the book Modernizing Legacy Applications In PHP and am now in the position where I need to replace global variables.

In my case we have both MySQL and MongoDB mixed heavily throughout the application using global variables: $database for MySQL and $mongo for MongoDB. I’m wondering what the best way to inject both of these databases would be. Most examples (in the book and elsewhere) have something like this:

class Database {
    public function __construct() {}
}

class MySQL extends Database {
    private $mysql;

    public function __construct() {
        $default_options = [
            PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::ATTR_EMULATE_PREPARES   => false,
        ];
        // get config from file
        $this->mysql = new PDO(...);
    }

    public function get_instance() { return $this->mysql; }

}

class MongoDB extends Database {

    private $mongodb;  

    public function __construct() {
        // get config from file
        $mongodb = new MongoClient(...);
    }

    public function get_instance() { return $this->mongodb; }
}

class User {

    private $database = null;
    private $table = "users";

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

}

// In another file:
$user = new User(new DatabaseMySQL);

That’s cool, but the problem I’m having is, when User stores its attributes like name,email, id, etc. in MySQL, and it stores something else like user_type in Mongo (obviously its more than this but I’m just giving an easy example), than how does dependency injection work?

Do I have to pass in two Database classes to the constructor?

Do I have a set_database function that I have to keep switching between when I want to make a call?

class User {

    private $database = null;
    private $table = "users";

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

    public function get_user() {
        $first_set = $this->database->run('select * from users',[]);
        $this->database->set_database(new DatabaseMongoDB);
        $second_set = $this->database->run('users',[]);
    }
}

I’m trying to understand how this would work, and would continue working if other developers added databases that had to be called in the User class (like Redis for example).

Source: Stackoverflow

Leave a Reply

Your email address will not be published. Required fields are marked *