mjpramos
mjpramos

Reputation: 543

How to manage multiple database connections in PHP PDO with SLIM

I've built a simple RESTful API in PHP with Slim Framework. I'm still new to OOP. I have a route which queries a database using PDO. Now I want to extend the API with more routes but I need to connect to different databases.

An example route:

$app->get('/usados/carrocarias', 'authenticate', function() {
        $response = array();
        $db = new DbHandler();

        // fetching all carrocarias
        $carrocarias = $db->getCarrocariasUsados();

        $response["error"] = false;
        $response["carrocarias"] = array();

        array_walk_recursive($carrocarias, function(&$val) {
            $val = utf8_encode((string)$val);
        });

        array_push($response["carrocarias"], $carrocarias);

        echoRespnse(200, $response, "carrocariasoutput");
    })->via('GET', 'POST');

My DbHandler class:

class DbHandler {

private $conn;

function __construct() {
    require_once dirname(__FILE__) . '/DbConnect.php';
    // opening db connection
    $db = new DbConnect();
    $this->conn = $db->connect();
}
...
}

And my DbConnect file:

class DbConnect {

private $conn;

function __construct() {        
}

/**
 * Establishing database connection
 * @return database connection handler
 */
function connect() {
    include_once dirname(__FILE__) . '/Config.php';

    // Connecting to mysql database
    $this->conn = new PDO("dblib:host=".DB_HOST.";dbname=".DB_NAME.";charset=UTF-8", DB_USERNAME, DB_PASSWORD);
    $this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // returing connection resource
    return $this->conn;
}
}

DB_HOST, DB_NAME, DB_USERNAME and DB_PASSWORD are defined in the Config.php. I know I need to add other credentials to Config.php for other databases.

How can I modify my classes and route so I can pass a variable to decide which database to connect to?

EDIT: I'm completing my question with what I think is the solution. At least for me and I hope it can help other noobs as I. Don't know if it's the best practise.

My DBConnect.php

<?php

class DbConnect {

private $conn;
public $selDatabase;

function __construct($strServer) {
    $this->selDatabase = $strServer;
}

/**
 * Establishing database connection
 * @return database connection handler
 */
function connect() {
    include_once dirname(__FILE__) . '/Config.php';

    try {
        switch($this->selDatabase) {
            case 'mysql-localhost':
                $this->conn = new PDO('mysql:host=localhost;dbname=task_manager','root', 'mkecdapl');
                break;

            case 'sqlsrv-localhost':
                $this->conn = new PDO("sqlsrv:server=".DB_HOST.";Database=".DB_NAME_NOVOS.";charset=UTF-8", DB_USERNAME, DB_PASSWORD) or die("failed to connect");
                break;

            case 'dbusados-localhost':
                $this->conn = new PDO("sqlsrv:server=".DB_HOST.";Database=".DB_NAME_USADOS, DB_USERNAME, DB_PASSWORD) or die("failed to connect");
                break;
            case 'dbusados':
                $this->conn = new PDO("dblib:host=".DB_HOST.";dbname=".DB_NAME_USADOS, DB_USERNAME, DB_PASSWORD) or die('failed to connect');
                break;

            case 'dbnovos-localhost':
                $this->conn = new PDO("sqlsrv:server=".DB_HOST.";Database=".DB_NAME_NOVOS, DB_USERNAME, DB_PASSWORD) or die("failed to connect");
                break;
            case 'dbnovos':
                $this->conn = new PDO("dblib:host=".DB_HOST.";dbname=".DB_NAME_NOVOS, DB_USERNAME, DB_PASSWORD) or die('failed to connect');
                break;
            case 'dbnovas':
                $this->conn = new PDO("dblib:host=".DB_HOST.";dbname=".DB_NAME_NOVAS, DB_USERNAME, DB_PASSWORD) or die('failed to connect');
                break;
        }

        $this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

        // returing connection resource
        return $this->conn;

    } catch (PDOException $e) {
        echo "DataBase Error: ".$e->getCode()." ".$e->getMessage();
    }
}

}

?>

My DBHandler is the same. The difference is in my routes. Instead of:

$db = new DbHandler();

I call the same method but with the appropriate database name:

$db = new DbHandler('dbusados');

Upvotes: 2

Views: 3109

Answers (1)

geggleto
geggleto

Reputation: 2625

Add each database connection as a depenency on the $app object.

you can setup different static methods to return the correct PDO object.

$app->db1 = DbConnect::getDatabase1;

class DbHandler {

private $conn;

public static function  getDatabase1() {
    require_once dirname(__FILE__) . '/DbConnect_Database1.php';
    // opening db connection
    $db = new DbConnect();
    $db->conn = $db->connect();
    return $db;
}
...
}

Upvotes: 2

Related Questions