Configuration settings are something that you have to deal with in just about every type of web application. The majority of web applications will have at least a database, but its pretty common to have a number of third-party providers who you rely upon for different services.

I think the problem of managing configuration data in web applications is solved in many different ways if you looked at any number of different frameworks. Developers I’ve spoken to often also have their preferred way of handling them too.

In this week’s tutorial I’m going to be looking at how to handle configuration data in your Laravel application. I’ve touched upon using configuration in a couple of tutorials in the past, but I think this is such a common thing you will need, it deserves a dedicated article too.

The configuration files

Unless you are totally new to Laravel, you will probably be already aware of where the configuration files are located in the default application structure. If you look under app/config you will see a number of different configuration settings broken up into individual files.

If you open one of the files you will see that it is basically just an array. This really simple setup makes it really easy to start creating your own custom configuration files because there isn’t a difficult structure to learn.

It’s also really easy to organise your configuration files because you can break them down into individual files.

You will also notice that there is a directory named testing. You can create environment specific files that will overwrite the default configuration files at runtime. This is really handy if you want to use an in-memory database during testing for example or if you wanted to set some specific settings for your local environment.

Have a read through the configuration files to see what options you have at your disposal. You will probably not want to change any of the default settings, but it’s good to know what you can change if you need to.

Setting your environment

Something that is easy to neglect when you are first developing your application is setting the environment. If you jump straight into cutting code you probably won’t think twice about configuring your application’s different environments correctly.

However once you get to the stage where you want to push your application to a staging or production server, you will need to set up your environments so your application has the correct configuration settings for that environment.

The environment of your Laravel application is handled in boostrap/start.php. In this file you will see the following code:

$env = $app->detectEnvironment(array(

‘local’ => array(‘your-machine-name’),

));  

By default your Laravel application will be in the production environment.

To define other environments you can add new key value pairs for each of your environments. For example:

$env = $app->detectEnvironment(array(  
‘local’ => array(‘philips-mbp.home’),  
‘staging’ => array(‘staging-server’),  
‘production’ => array(‘production-server’)  
));  

philips-mbp.home refers to the hostname of the computer. If you go into your command line and run the hostname command you will be returned the name of the computer.

In Laravel you used to be able to set up your environments using a URL pattern. This is no longer a feature out of the box, but you could pass the detectEnvironment method a closure that would reinstate this functionality if you really wanted.

Personally, I much prefer setting the environment via the hostname.

Using the Config facade

Now that you have your configuration set up correctly you can start using these options in your code. This makes it really easy to abstract any of your custom settings into your configuration files so you can switch based on environments and you don’t have configuration settings polluting your application.

For example, imagine you had an expiring time in minutes set in your configuration settings. To retrieve this value you could write:

$minutes = Config::get(‘cache.expiry’);  

In the example above, cache is the file name and expiry is the key. Here you are basically just using dot notation to select the value from an array.

You can set a default by passing a second parameter:

$minutes = Config::get(‘cache.expiry’, 10);  

And you also set the configuration item, but this will only last for the current request:

Config::set(‘cache.expiry’, 10);  

Using config files in service providers

I think one of the most common scenarios where you need access to the application’s configuration is in your service providers. Service providers are a way to “bootstrap” your code and prepare services that can be used in your application.

For example, say I wanted to specify how often the cache should expire in my configuration. I could set up my repository like this:

/**  
* Register User Repository  
*/  
public function registerUserRepository()  
{  
$this->app->bind(‘Cribbb\Repositories\User\UserRepository’, function($app)  
{  
$user = new EloquentUserRepository( new User, $app[‘hash’] );

$minutes = $app[‘config’]->get(‘cache.expires’);

return new CacheDecorator( $user, new LaravelCache( $app[‘cache’], ‘user’, $minutes) );  
});  
}  

Within your service providers you can access the config instance from the $this->app class property. This is exactly the same instance as when using the facade, so you can get and set configuration properties in pretty much the same way.

Using dot files

Laravel’s default configuration structure is an excellent way of handling the multitude of configuration settings you will end up requiring in your application. It also make it really easy to set up your own configuration settings and access them in the same way.

However when it comes to sensitive configuration settings, using this method is not always advisable.

For example, you probably don’t want to keep your database details committed to your git repository and you will only really need to use certain configuration details in the production environment.

It can also be really big pain when you are working with many other developers, each of who have their own local database with a different username and password depending on their set up. Keeping the local configuration files out of version control is not always a workable solution.

Instead Laravel provides us with a very neat solution in dot files.

A dot file is basically a file that sits in the root of the project directory and contains any sensitive or environment based configuration details that shouldn’t be committed to your project.

For each environment you can simply create a dot file and those configuration details will be included in your code.

For example, create a file called .env.local.php. This will sit in your local project directory. You will also need to add the following line to your .gitignore file to ensure that the file isn’t added to your git repository:

.env.local.php  
[/bash]

Now in your `.env.local.php` file you can create an array of sensitive configuration details for the current environment:  
```php  
<?php  
return array(  
‘DATABASE_NAME’ => ‘my_database’,  
‘DATABASE_USER’ => ‘username’,  
‘DATABASE_PASSWORD’ => ‘totally_secure_password’  
);  

Now in your database.php configuration file you can replace the hardcoded details with the environment variables:

‘database’ => $_ENV[‘DATABASE_NAME’],  
‘username’ => $_ENV[‘DATABASE_USER’],  
‘password’ => $_ENV[‘DATABASE_PASSWORD’]  

In each of your different environments (or whenever a new developer wants to set up a local version) you can create a new dot file to hold the local configuration details. This will keep your configuration details secure and you won’t have the headache of having to deal with it in version control.

Conclusion

Configuration data seems to be one of those problems that is handled in a lot of different ways. Getting the wrong database details or api key for a third-party service is not something you want to mess up in production, so it’s good to get this stuff down early on in your application.

Laravel also make setting your environment really easy. I’m a big fan of setting the environment based upon the hostname of the computer. Dealing with different environments can be hairy when setting the environment isn’t exactly clear cut.

It’s amazing how many configuration items you will end up needing in a web application. Almost all web application require a database, and it’s quite common to use many different third-party services for common tasks such as sending email or dealing with bugs. Keeping a copy of all of these sensitive configuration details outside of your version control and stored locally on the server that requires them is an excellent solution to a very unnecessary problem.

This is a series of posts on building an entire Open Source application called Cribbb. All of the tutorials will be free to web, and all of the code is available on GitHub.

To view a full listing of the tutorials in this series, click here.