Yii2 set db connection at runtime - php

In my Yii2 (basic application) web.php I configure a NULL db connection as 2nd database connection.
This needs to be filled with valid parameters which are coming from a record on the main db connection:
'db' => require(__DIR__ . '/db.php'),
'db2' => [
'class' => 'yii\db\Connection',
'dsn' => NULL,
'username' => NULL,
'password' => NULL,
'charset' => 'utf8',
],
After initializing the app() i need to fill out the NULL parameters with values that i retrieve from another database to further use it in models.
How can i achieve this in Yii2?

No problem, it is supported
\Yii::$app->db2->close(); // make sure it clean
\Yii::$app->db2->dsn= 'yourdsn';
\Yii::$app->db2->username = 'username';
\Yii::$app->db2->password = 'password';
Done, now you can use it
Yii::$app->db2->...
Another way:
$connection = new \yii\db\Connection([
'dsn' => $dsn,
'username' => $username,
'password' => $password,
]);
$connection->open();
$command = $connection->createCommand('SELECT * FROM post')->....;
Refer: http://www.yiiframework.com/doc-2.0/yii-db-connection.html

Related

Yii2 dynamic connection to second database

I have a simple select in my View code. It represents list of cities and on my server there're several databases which are responsible for each city. I have my Model code and it takes city_id. Depends on it I want to connect to database and seek for needed data in it. I've added second database to my components like:
'db' => require(__DIR__ . '/db.php'),
'db2' => require(__DIR__ . '/db_login.php'),
and two files which returns database connection.
File 1:
'class' => 'yii\db\Connection',
'dsn' => $dsn,
'username' => $username,
'password' => $password,
'charset' => 'utf8',
File 2:
'class' => 'yii\db\Connection',
'dsn' => $dsn,
'username' => $username,
'password' => $password,
'charset' => 'utf8',
I want to change my database name somehow dynamically right after users' choice.
You can do a call for dbconnection
$actual_dsn = 'your_dns_actual_value'
$yourConnection = new \yii\db\Connection([
'dsn' => $actual_dsn,
'username' => $username,
'password' => $password,
]);
$yourConnection->open();
eventually close the previous open connection
You can do this in your db_login.php depending of the application's needs
Maybe :
if (choice =='a') {
'db' => require(__DIR__ . '/db.php')
}
else {
'db2' => require(__DIR__ . '/db_login.php')
}

DB::raw() always uses default database

I've been searching for a while for a solution here but no luck. I have a model named Currency which extends eloquent.
class Currency extends Eloquent {
protected $connection = 'currency';
protected $table = 'dbo.sfCXDetail';
public $timestamps = false;
public function monthlyTransactions(){
return Currency::select(array(DB::raw('COUNT(trx_number) AS Transactions'), DB::raw('MONTH(update_stamp) as TransactionsMonth')))
->whereBetween(DB::raw('DATEPART(YYYY, update_stamp)'), array(2012,2012))
->groupBy(DB::raw('YEAR(update_stamp)'))
->groupBy(DB::raw('MONTH(update_stamp)'))
->orderBy(DB::raw('YEAR(update_stamp)'))
->orderBy(DB::raw('MONTH(update_stamp)'))
->get();
}
}
The problem is, DB::raw uses the default database inside the database config file, so when I try using:
Currency::raw()
I get an error
strtolower() expects parameter 1 to be string, object given
The database I'm using can't be used as the default database. How do I use the DB::raw method with the current database in use inside the model?
This query works without error when I set the default database to 'currency', but not if I set it to use my local default mysql database.
This is in my DB config file:
'currency' => array(
'driver' => 'sqlsrv',
'host' => 'xx',
'database' => 'xx',
'username' => 'xx',
'password' => 'xx',
'prefix' => '',
),
You can try something like this:
DB::connection('specialConnection')->raw(...);
Also, you have to add another config settings for that connection like:
'currency' => array(
'driver' => 'sqlsrv',
'host' => 'xx',
'database' => 'xx',
'username' => 'xx',
'password' => 'xx',
'prefix' => '',
),
'specialConnection' => array(
'driver' => 'mySql',
'host' => 'xxx',
'database' => 'xxx',
'username' => 'xxx',
'password' => 'xxx',
'prefix' => '',
)
I could be wrong but I believe that setting the connection property as a protected property of Currency would not also set connection for the DB class.
would something like this work (I am at work at not able to test, sorry):
$db = new DB;
$db->connection = 'currency'
$db->table = 'dbo.sfCXDetail';
...
return Currency::select(array($db->raw('COUNT(trx_number) ...
...
I think it's a scope thing

How to setup an SSL encrypted MySQL connection with Doctrine2 in PHP (not Symfony, not Doctrine1)

I am having a hard time finding documentation / examples of how to setup an SSL encrypted connection with Doctrine2 to MySQL. I'm not using Symfony, so looking for the pure PHP path.
What I'm stuck on is basically how to convey the MYSQL_CLIENT_SSL (or MYSQLI_CLIENT_SSL) flag, and the path to the ca certificate. I can live with not verifying the certificate, but I can't live with not encrypting the connection for this task.
On the command line this would be done similar to this:
mysql --ssl-verify-server-cert --ssl-ca=/mysql-ssl-certs/ca-cert.pem --ssl -h host [etc]
In pure php using the mysql extension I think it would look something like:
$conn = mysql_connect($host, $user, $pass, false, MYSQL_CLIENT_SSL);
With mysqli (i think) it would be something like this:
$db = mysqli_init();
$db->ssl_set(null, null, $cert, null, null);
$db->real_connect($host, $user, $pass, $dbname);
The question is, how do I do this with Doctrine2? Is it even possible? How do I modify the initialization for Doctrine2 to do this?
$DOCTRINE2_DB = array(
'driver' => 'pdo_mysql',
'host' => $host,
'user' => $user,
'password' => $pass,
'dbname' => $dbname,
'unix_socket' => $sockpath,
);
$DOCTRINE2_EM = \Doctrine\ORM\EntityManager::create($DOCTRINE2_DB, $DOCTRINE2_CONFIG);
$EM =& $DOCTRINE2_EM; // for brevity & sanity
You should be able to add an additional parameter driverOptions and set the appropiate SSL configuration for PDO
http://es1.php.net/manual/es/ref.pdo-mysql.php#pdo-mysql.constants
$DOCTRINE2_DB = array(
'driver' => 'pdo_mysql',
'host' => $host,
'user' => $user,
'password' => $pass,
'dbname' => $dbname,
'unix_socket' => $sockpath,
'driverOptions' => array(
PDO::MYSQL_ATTR_SSL_CA => '...',
PDO::MYSQL_ATTR_SSL_CERT => '...',
PDO::MYSQL_ATTR_SSL_KEY => '...'
)
);
I can't test it but looking at the code here I think it should work
[EDIT BY ASKER:]
Here is how it worked for me:
$DOCTRINE2_DB = array(
'driver' => 'pdo_mysql',
'host' => $host,
'user' => $user,
'password' => $pass,
'dbname' => $dbname,
'unix_socket' => $sockpath,
'driverOptions' => array(
PDO::MYSQL_ATTR_SSL_CA => '/file/path/to/ca_cert.pem',
)
);

Add connection to DBAL dynamically in Silex

I am writing a PHP application using the Silex framework. I'm using the Doctrine Service Provider, and I can open a connection normally as this:
$app->register(new Silex\Provider\DoctrineServiceProvider(), array(
'dbs.options' => array (
'localhost' => array(
'driver' => 'pdo_mysql',
'host' => 'localhost',
'dbname' => 'test',
'user' => 'root',
'password' => 'root',
'charset' => 'utf8',
)
),
));
That works perfectly. What I want now is to add another database connection afterwards in my code. I know I can do it adding another element to dbs.options, but I want to do it afterwards, in the controllers (as different controllers will use different database connections).
Is that possible? I guess I could use something like DriverManager::getConnection($options, $config, $manager); but there's probably a better way to do it.
Thanks!
$conn = DriverManager::getConnection($params, $config);
this is original code to generate new connection, so what you wrote is ok
Link: http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/data-retrieval-and-manipulation.html
You can configure multiple db connections using the DoctrineServiceProvider bundled with Silex.
Replace the db.options with an array of configurations where keys are connection names and values configuration options.
$app->register(new Silex\Provider\DoctrineServiceProvider(), array(
'dbs.options' => array (
'mysql_read' => array(
'driver' => 'pdo_mysql',
'host' => 'mysql_read.someplace.tld',
'dbname' => 'my_database',
'user' => 'my_username',
'password' => 'my_password',
'charset' => 'utf8',
),
'mysql_write' => array(
'driver' => 'pdo_mysql',
'host' => 'mysql_write.someplace.tld',
'dbname' => 'my_database',
'user' => 'my_username',
'password' => 'my_password',
'charset' => 'utf8',
),
),
));
Access multiple connections in your controllers:
$app->get('/blog/{id}', function ($id) use ($app) {
$sql = "SELECT * FROM posts WHERE id = ?";
$post = $app['dbs']['mysql_read']->fetchAssoc($sql, array((int) $id));
$sql = "UPDATE posts SET value = ? WHERE id = ?";
$app['dbs']['mysql_write']->executeUpdate($sql, array('newValue', (int) $id));
return "<h1>{$post['title']}</h1>".
"<p>{$post['body']}</p>";
});
Source: http://silex.sensiolabs.org/doc/providers/doctrine.html

Doctrine2: additional connection options

Is there a way to add some additional parameters to the database connection in Doctrine2?
For example I need to enable network communication compression.
$DoctrineConnectionOptions = array(
'driver' => 'pdo_mysql',
'dbname' => 'db',
'user' => 'root',
'password' => 'root',
'host' => 'localhost',
/*
additional_options => array(
PDO::MYSQL_ATTR_COMPRESS => true
)
*/
);
$em = \Doctrine\ORM\EntityManager::create($DoctrineConnectionOptions, $DoctrineConfig);
Check EntityManager::create() source code. You can directly pass customly made PDO object as a connection option ('pdo' key).

Categories