1

we converted to 3.3.3 from 2.5.5.

a concurrent connection to a secondary database (set up using Focus Lab Master Config in both versions) works in 2.5.5 but i get warnings in 3.3.3 with message Warning

Illegal string offset 'hostname'.

it finally completely fails when it tries to run the query and prefixes tables with the primary connection db name instead of the secondary db name.

its loading the primary connection db instead of the secondary connection - all tables names are prefixed with primary connection db name.

we used this syntax in 2.5.5 - $this->EE->load->database('secondary_connection', TRUE);

and in the environment specific config for my local is

$env_config['database'] = array (

'expressionengine' => array (
        'hostname' => 'localhost',
        'username' => 'xxxx',
        'password' => 'xxxxx',
        'database' => 'xxxxx',
        'dbdriver' => 'mysqli',
        'dbprefix' => 'exp_',
        'pconnect' => FALSE
    ),

'ext_db_components' =>
    array (
            'hostname' => 'localhost',
            'username' => 'xxxxx',
            'password' => 'xxxxx',
            'database' => 'xxxxx',
            'dbdriver' => 'mysqli',
            'dbprefix' => '',
            'pconnect' => FALSE,
            'cache_on' => FALSE,
    ),

);

the error appears on a page that calls a model.

in one of the model methods, it needs to access an external db (housed on same mysql server).

in EE2, loading that external connection using
$this->components_db = $this->EE->load->database('ext_db_components', TRUE);
let us query against it using active record.

the same line of code in EE3 throws Illegal string offset 'hostname' warnings before finally failing with a mysql exception.

FYI - it does appear to be calling the legacy db.php connector (/system/ee/legacy/database/DB.php) rather than the EE3 db connector

is there a way to concurrently connect to an external db using config settings in 3.3.3?

NOTE: I am not asking about switching primary connections based on environment - i need multiple concurrent connections in the same environment.

  • Same issue/errors here, with a minor exception that we use $db2 = ee()->load->database('second_database',true); Wondering if anyone has an answer to this issue. It's a bit of a show stopper for using EE3. – Out of Control May 26 '17 at 16:21
4

Please see the documentation for full details: Connecting to an External Database

But the basic pattern for spinning up a separate DB connection in v3 would be:

  1. Create a DBConfig object from your database's connection settings
  2. Create a new Database object using the DBConfig object
  3. Issue queries to a Query object on the new database with ->newQuery(), using all standard methods (select(), get(), etc.)

Step 1 is accomplished with the following (ensure that your class references the namespace with use EllisLab\ExpressionEngine\Service\Database;:

$db_config = new Database\DBConfig(ee('Config')->getFile());
$db_config->getGroupConfig('other_db');

Step 2 with:

$db = new Database\Database($db_config);

And Step 3, your queries with:

$query = $db->newQuery()->get('my_table');

That pattern is best implemented as services in your addon.setup.php file. This makes sure you are only connecting one time for each page request, and keeps your syntax simple, and consistent with connections to ExpressionEngine's database.

'services' => array(

  // This service will be used to query our external database
  // e.g., ee('my_addon:db')->select()
  'db' => function($addon)
  {
    return $addon->make('my_addon:Database')->newQuery();
  },

  // This service manages our external database connection
  // e.g., ee('my_addon:Database')->getLog()
  'Database' => function($addon)
  {
    // Makes sure we only do this work once per page request
    static $db;

    if (empty($db))
    {
      // fetch config from system/user/config/my_addon_database.php
      $config = ee('Config')->getFile('my_addon_database');

      // create the DBConfig object
      $db_config = new Database\DBConfig($config);

      // select the database connection group
      $db_config->getGroupConfig('my_addon');

      // connect to and make the Database object
      $db = new Database\Database($db_config);
    }

    return $db;
  }
)

Doing this will let you make calls using ee('my_addon:db')-> exactly as you would ee('db')-> to the ExpressionEngine database.

  • Closer, but not quite there yet. Now getting: Argument 1 passed to EllisLab/ExpressionEngine/Service/Database/Database::__construct() must be an instance of EllisLab/ExpressionEngine/Service/Database/DBConfig, array given – Out of Control May 26 '17 at 19:08
  • Verified that $db_config->getGroupConfig('secondary_database') does return an array and not an instance of DBConfig. Bug or another way to get the proper instance? – Out of Control May 26 '17 at 19:19
  • Sorry, was going from memory and it's been awhile since I connected out to a secondary database within the app. Edited the answer, let me know if you have issues using it now. – Derek Jones May 26 '17 at 19:28
  • Would be nice to see these sorts of things added to the transition docs for EE2 -> EE3 – Out of Control May 26 '17 at 20:04
  • Updated the answer and added a documentation link ;) – Derek Jones Jun 19 '17 at 18:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.