Configuration in CakePHP 3.0 Sep 05 2012

Early work has started for CakePHP 3.0, and I’ve started re-visiting how CakePHP handles configuration and bootstrapping. I want to focus on configuration for this post, as bootstrapping, while related is worthy of its own post. The goal of this post is to provide some context on the planned changes, and to get feedback on those changes. My hope is that by getting feedback early on we can avoid problems & surprises later on.

I decided to start with configuration. Every application needs at some configuration even in a conventions over configuration framework like CakePHP. I feel that configuration can be improved from where it stands today, as there are a few problems.

Problems with configuration

When I think of configuation in CakePHP, I think of the Configure class. From talking with others, they feel the same. Configure has been around as long as CakePHP, and is the primary way most developers do configuration for their application/plugins. However, there are two other ways that configuration is currently managed outside of Configure :

Classes like DATABASE_CONFIG and EmailConfig . These classes are my least favorite method. They are clunky and don’t really offer much benefit over Configure in terms of flexibility.

and . These classes are my least favorite method. They are clunky and don’t really offer much benefit over in terms of flexibility. Configuration methods like Cache::config() and CakeLog::config() . While these methods appear to offer more traditional dependency injection, they don’t. All engine class references are passed as strings, and you can never inject an instance anywhere.

While having 3 ways to do configuration may not seem like a problem for the experienced developer. But having 3 ways to do basically the same thing creates a steeper learning curve for developers who are new to CakePHP. Ideally, there would be only one way configuration is handled. Having systems like DATABASE_CONFIG greatly increases the difficulty in creating configuration files in formats other than PHP.

Proposed solution

Originally, I was very much in favour of removing the configuration classes and adding more config() methods to the remaining classes needing them. However, Jose and Juan argued that using Configure was a better solution because we’d still need to maintain Configure . We’d still have 2 ways of doing configuration by adopting config() methods, while the goal was 1. While I don’t like that many clasess in CakePHP will be coupled to Configure . I want to avoid adding additional layers just to provide what I think will be a marginal amount of decoupling. While an additional layer could be more ‘proper’ it would also increase difficulty for beginners. Despite the downside of coupling there are some great benefits to putting all configuration in Configure :

All core, app, and plugin classes only need one way to create, read and manage configuration.

We can leverage the existing Config adapters to enable support for any format/source.

Familliarity and simplicity. Existing developers are familliar with Configure, and its a very basic API so its easy for new developers to pick up.

While Configure would be the primary way to handle configuration in a 3.0 application, we’re planning on adding more generic setter injection where it makes sense. For example, you’ll be able to directly add cache engines to Cache :

<?php use Vendor\Caching\CustomEngine ; $engine = new CustomEngine ( $dependency ) ; Cache :: engine ( 'custom' , $engine ) ;

This feature allows you to easily accomodate any type of caching that can’t or doesn’t make sense to store as configuration. In these situations, you’ll be able to use engine() on Cache, and Log to set a specific instance. Other adapter based classes will have similar features.

I’m interested to hear any feedback on these plans. I’m still in the early stages of implementing them and would love to hear people’s thoughts before finishing. If you’re interested in seeing the in progress changes you can find them on my github fork .