Skip to content

Unify configuration

Mark Story edited this page Aug 21, 2013 · 6 revisions

Proposal 1

Some configuration like that used for database and email configuration should be normalized with the rest of configuration in CakePHP, instead of defining a class methods should be used on the correct container:

<?php
// app/Config/database.php
use Cake\Database\ConnectionManager;

ConnnectionManager::create('default', [
   // details.
]);

// app/Config/email.php
use Cake\Network\EmailConfig;

EmailConfig::create('default', [
   // details.
]);

These example API's create a more congruent api to how Configure is used to manage configuration for other aspects of CakePHP. It would also be possible to put all configuration into Configure, and have classes like Cake\Network\Email and Cake\Database\ConnectionManager get the required configuration from there as needed. Email.default and Datasource.default would be example configuration paths.

Pros

  • Dependencies are injected.
  • No global registry for configuration data.
  • Many similar public methods in different classes.
  • No synchronization issues.

Cons

  • No global registry for configuration data.
  • Similar code in several places, although base classes could be created to handle this.

Proposal 2

Having to learn all the various methods on various classes can create a bit of mental overhead for developers. They also make storing configuration data as ini, XML or other formats more challenging. Additionally historically CakePHP has used Configure for most configuration data, and encouraged its use for application configuration.

Instead of various config() methods on classes like Email, Cache etc. All configuration data would be stored and pulled from Configure as required.

<?php
// In the bootstrapping process.
Configure::write('Cache.default', [
   'engine' => 'Apc',
   'prefix' => 'kick_ass_app_',
   'duration' => '+1 day'
]);

// If the default adapter has not already been created, the configuration data
// be read from configure and the adapter will be created, and then used.
$data = Cache::read('my_data', 'default');

Once a configured adapter is constructed, then configuration updates will not be propagated. Instead when modifying configuration data that might already be concrete, you should use the relevant drop() method.

<?php
// Update the default cache config
Cache::drop('default');
Configure::write('Cache.default.duration', '+3 days');

As an additional change all the existing config() methods should be removed. Having two ways to do the same thing feels wrong and not like something that CakePHP should be doing.

Pros

  • All classes can be lazy loaded.
  • All configuration is done in one place, in one class.
  • Familiarity for existing developers.
  • Trivial to make all configuration ini or xml/json/yaml based.
  • Simple to remember, easy to use.

Cons

  • Tighter coupling. Many classes will depend on Configure for adapters etc.
  • Dependency injection is harder as all configuration is pulled from Configure.
  • Synchronization issues are possible.

Status

The changes described in Proposal 1 and Config methods here have been implemented in 3.0