0

Before anyone says this question has been answered already, do note that while defining multiple pdo connections in a container has already been explained here and here, my question is more around the best approach to building dynamic pdo connections from a json object fetched from a master database.

I have the following Database class I use to create any database connection I need, where and whenever they are needed.

class Database {

    private static $dbs = array();

    # we declare as static so the state is kept between function calls to connect
    # this allows to connect just once to the database and then just return the connection
    # on future function calls
    private static $conn = null;

    # now since we dont want to reinstiate the class anytime we need it, lets also set the constructor to private
    private function __construct(){}

    #  get the database connection
    public static function connect( $name, $opt, $struct, $key = null ) {
        if( empty( self::$dbs[$name] ) ) {
            try {
                $struct['username'] = ( null === $key ) ? $struct['username'] : Security::XORDecrypt( $struct['username'], $key );
                $struct['password'] = ( null === $key ) ? $struct['password'] : Security::XORDecrypt( $struct['password'], $key );

                switch( $struct['type'] ) {
                    case 'sqlsrv': # MSSQL
                        self::$conn = new PDO( "sqlsrv:server=" . $struct['hostname'] . ";" . "ConnectionPooling=1;" .  "database=" . $struct['database'], $struct['username'], $struct['password'], array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::SQLSRV_ATTR_QUERY_TIMEOUT => intval( $struct['timeout'], 10 ) ) );
                    break;
                }

                self::$dbs[$name] = self::$conn;
                return self::$conn;
            }
            catch( PDOException $ex ) {
                if( $opt == 1 )
                    echo "<p class='bg-danger'>Connection error: " . $ex->getMessage() . "</p>";
                else
                    die( json_encode( array( 'outcome' => false, 'message' => 'Unable to connect' ) ) );
            }
        }
        return self::$dbs[$name];
    }

    public static function disconnect( $name ) {
        if( self::$dbs[$name] != NULL ) {
            self::$dbs[$name] = NULL;
        }
    }
}

And whenever I need to connect to a database it's done like this

$pre = '_' . $app_id; $$pre = ''; 
$conn = Database::connect( $pre, $env['options']['env'], $apps['db_conns'][$app_id], $i_key );

In the above:

$app_id: stores the id of the application instance who's data is being requested

$env['options']['env']: stores the environment we're operating under, development/production etcetera.

$apps['db_conns'][$app_id]: is a multi associative array which stores the database connection details (username/password/port) and etcetera per database

$i_key: stores the hash that was used to encrypt the connection details (fetched from another process)

Then the $conn is passed into the Class performing the requested database action. When the connection is no longer needed I close using

Database::disconnect( $pre );
John Conde
  • 217,595
  • 99
  • 455
  • 496
David Webb
  • 26
  • 3
  • What's the question? What problem are you having? – Alex Howansky Dec 30 '20 at 19:11
  • The question is how would I implement a class like what I have using Slim 4. In Slim 4, most methods I've seen discuss knowing the db connection details ahead of time. – David Webb Dec 30 '20 at 19:16
  • There's nothing about Slim that will prevent this class from working as is. – Alex Howansky Dec 30 '20 at 19:19
  • Ok, let me be more specific. The question should have been How would I instantiate new PDO connections on the fly using a Repository? However, I think I understand what needs to be done. Typically one would instantiate a PDO class in the container definitions and then use that PDO class in the repository. However, since the database connection details may not be known yet, rather than using that PDO in the specific repository, use my Database class instead. Is this what you were alluding to? – David Webb Dec 30 '20 at 20:15
  • I just updated this [article](https://odan.github.io/2020/04/05/slim4-multiple-pdo-database-connections.html#multi-tenancy-environment) – odan Dec 30 '20 at 21:01
  • Thanks for the Update @odan – David Webb Dec 30 '20 at 21:06
  • Please add details to your question and describe what is the exact problem you are trying to solve in an Slim application. – Nima Dec 31 '20 at 06:28

0 Answers0