How to use multiple databases dynamically for one model in CakePHP
This gentleman (Olivier) had the same problem! (A year ago) He wrote a small adaptation for the Controller
s! It's pretty small and it turns out, it works in 1.3 and 2.x.
Anyhow, this is my final solution, that I put in the app/Model/AppModel.php
:
class AppModel extends Model
{
/**
* Connects to specified database
*
* @param String name of different database to connect with.
* @param String name of existing datasource
* @return boolean true on success, false on failure
* @access public
*/
public function setDatabase($database, $datasource = 'default')
{
$nds = $datasource . '_' . $database;
$db = &ConnectionManager::getDataSource($datasource);
$db->setConfig(array(
'name' => $nds,
'database' => $database,
'persistent' => false
));
if ( $ds = ConnectionManager::create($nds, $db->config) ) {
$this->useDbConfig = $nds;
$this->cacheQueries = false;
return true;
}
return false;
}
}
And here is how I used it in my app/Controller/CarsController.php
:
class CarsController extends AppController
{
public function index()
{
$this->Car->setDatabase('cake_sandbox_client3');
$cars = $this->Car->find('all');
$this->set('cars', $cars);
}
}
I'm betting, I'm not the first or last one with this problem. So I really hope this information will find people & the CakePHP community.
CakePHP using multiple databases for models
This site has a way to do it, but it's a little hacky.
CakePHP 3 Multiple Databases
Follow the Below Instructions
Step 1 : Open
config/app.php
FindDatasources
array and addRemote Database
configuration like as -
'Datasources' => [
'default' => [
'className' => 'Cake\Database\Connection',
'driver' => 'Cake\Database\Driver\Mysql',
'persistent' => false,
'host' => 'localhost',
'port' => '3306',
'username' => 'YOUR_DB_USER',
'password' => 'YOUR_DB_PASS',
'database' => 'YOUR_DB_NAME',
'encoding' => 'utf8',
'timezone' => 'UTC',
'flags' => [],
'cacheMetadata' => false,
'log' => false,
'quoteIdentifiers' => false,
'url' => env('DATABASE_URL', null),
],
'remote_db_1' => [ /*Remote Database 1*/
'className' => 'Cake\Database\Connection',
'driver' => 'Cake\Database\Driver\Mysql',
'persistent' => false,
'host' => '192.168.1.47', /*YOUR_REMOTE_SERVER_IP*/
'port' => '3306',
'username' => 'REMOTE_DB_USER',
'password' => 'REMOTE_DB_PASS',
'database' => 'REMOTE_DB_NAME',
'encoding' => 'utf8',
'timezone' => 'UTC',
'flags' => [],
'cacheMetadata' => false,
'log' => false,
'quoteIdentifiers' => false,
'url' => env('DATABASE_URL', null),
],
'remote_db_2' => [ /*Remote Database 2*/
'className' => 'Cake\Database\Connection',
'driver' => 'Cake\Database\Driver\Mysql',
'persistent' => false,
'host' => '192.168.1.47', /*YOUR_REMOTE_SERVER_IP*/
'port' => '3306',
'username' => 'REMOTE_DB_USER',
'password' => 'REMOTE_DB_PASS',
'database' => 'REMOTE_DB_NAME',
'encoding' => 'utf8',
'timezone' => 'UTC',
'flags' => [],
'cacheMetadata' => false,
'log' => false,
'quoteIdentifiers' => false,
'url' => env('DATABASE_URL', null),
],
Step 2 : Now you can access
Remote database
in your controller like as-
use Cake\Datasource\ConnectionManager;
use \PDO;
class YourController extends AppController{
public function getRemoteData(){
$conn1 = ConnectionManager::get('remote_db_1'); #Remote Database 1
$conn2 = ConnectionManager::get('remote_db_2'); #Remote Database 2
}
}
Note: Now you can use
PDO
methods to Insert,Retrieve,Update
Example :
class YourController extends AppController{
public function getRemoteData(){
$conn1 = ConnectionManager::get('remote_db_1'); #Remote Database 1
$sql = "SELECT * FROM users";
$query = $conn1->prepare($sql);
$query->execute();
$result = $query->fetchAll(); #Here is the result
}
}
Dynamically change database connection in cakephp 3
Use the ConnectionManager::config()
function to create connections on the fly and the ConnnectionManager::alias()
method to make all your Table classes use it by default.
There is a very good article describing the process here:
http://mark-story.com/posts/view/using-cakephp-and-a-horizontally-sharded-database
The only difference is that you can create the connection config on the fly instead of declaring the shards manually as it was shown in that article.
Retrieve associated model from different database using cakephp 3
You could try setting the strategy
in the association to select
. This might help. There's no full support for cross schema associations yet. I've put some work into it but it won't solve all cases.
I'm not sure in which CakePHP 3 version it got merged but I do recommend staying up-to-date with the release cycles.
Multiple database connection in cakephp 3
You can declare the defaultConnectionName()
method on the tables that will use by default another connection. In any of your Table classes:
public static function defaultConnectionName()
{
return 'another_config_name';
}
Related Topics
How to Logout from a Session in PHP
Laravel: How to Change the Default Auth Password Field Name
Symfony2 - Creating Own Vendor Bundle - Project and Git Strategy
Doing Http Requests from Laravel to an External API
Formulas to Calculate Geo Proximity
How to Validate a Credit Card in PHP
Only Variable References Should Be Returned by Reference - Codeigniter
Laravel 5.4 on PHP 7.0: Pdo Exception - Could Not Find Driver (Mysql)
Soap PHP Fault Parsing Wsdl: Failed to Load External Entity
In PHP, Is There a Short Way to Compare a Variable to Multiple Values
How to Check If a Url Exists in PHP
Phpmyadmin - Count(): Parameter Must Be an Array or an Object That Implements Countable
MVC (Laravel) Where to Add Logic
Two Simultaneous Ajax Requests Won't Run in Parallel