1. The Laravel framework has become very popular, between others, for its simplicity and expressiveness. With the recent release of Laravel v5, most of the core dependencies were updated. The same applies to illuminate/config, which is responsible for containing our
    app’s configuration.

We are often involved in projects not using the framework. Today, we will see how to use Laravel’s config package illuminate/config in a non-Laravel project. The code of this blog post is shared on github. Let’s get started!

Our dependencies

First things first: Using composer, we install illuminate/config, vlucas/phpdotenv and symfony/finder :

{% highlight bash %}
$ composer require illuminate/config
$ composer require vlucas/phpdotenv
$ composer require symfony/finder
{% endhighlight %}

PHP dotenv

Maybe the most required feature of a configuration system is having different configurations for different environments.
We use the package vlucas/phpdotenv to detect the current environment.
If you ‘re not familiar with it, it imports key-values defined in a .env file and makes these values available as environment variables.

For example if we create the following .env file:

{% highlight bash %}
$ composer require illuminate/config
$ composer require vlucas/phpdotenv
$ composer require symfony/finder
{% endhighlight %}

Then we can access the environment variable like this:

{% highlight php %}
<?php

Dotenv::load($env_file_path);

echo getenv('ENVIRONMENT'); // local
{% endhighlight %}

Symfony Finder Component

symfony/finder finds files and directories. We use it to search for the config files in the config dir.

This example will return an array of files for every php file located under the given directory:

{% highlight php %}
<?php

use SymfonyComponentFinderFinder;

$phpFiles = Finder::create()->files()->name('*.php')->in($path)->depth(0);
{% endhighlight %}

The Config class

First, we create the class Config extending IlluminateConfigRepository and add the following methods:

  • getConfigurationFiles($environment) returns the config files for the selected environment.
  • loadConfigurationFiles() defines the default configuration values and then merges the values for the current environment.
{% highlight php %}
<?php

use IlluminateConfigRepository;
use SymfonyComponentFinderFinder;

class Config extends Repository
{
/**

Load the configuration items from all of the files.

 

@param string $path

@param string|null $environment
*/
public function loadConfigurationFiles($path, $environment = null)
{
$this->configPath = $path;
 
foreach ($this->getConfigurationFiles() as $fileKey => $path) {
    $this->set($fileKey, require $path);
}

foreach ($this->getConfigurationFiles($environment) as $fileKey => $path) {
    $envConfig = require $path;

    foreach ($envConfig as $envKey => $value) {
        $this->set($fileKey.'.'.$envKey, $value);
    }
}
}
/**

Get the configuration files for the selected environment

 

@param string|null $environment

 

@return array
*/
protected function getConfigurationFiles($environment = null)
{
$path = $this->configPath;
 
if ($environment) {
    $path .= '/' . $environment;
}

if (!is_dir($path)) {
    return [];
}

$files = [];
$phpFiles = Finder::create()->files()->name('*.php')->in($path)->depth(0);

foreach ($phpFiles as $file) {
    $files[basename($file->getRealPath(), '.php')] = $file->getRealPath();
}

return $files;
}
}
{% endhighlight %}

The Application class

This is where the config instance is created.

  • First we define the project paths and define the current environment.
  • Then, we load the configuration files in the config class.
{% highlight php %}
<?php

class Application
{
/**

@var Config
*/
public $config;
 
/**

@var array
*/
protected $paths = [];
 
/**

Initialize configuration.
*/
public function __construct()
{
$this->setupPaths();
$this->config = new Config();
$this->config->loadConfigurationFiles(
$this->paths['config_path'],
$this->getEnvironment()
);
}
 
/**

Initialize the paths.
*/
private function setupPaths()
{
$this->paths['env_file_path'] = DIR . '/../';
$this->paths['env_file'] = $this->paths['env_file_path'].'.env';
$this->paths['config_path'] = DIR . '/../config';
}
 
/**

Detect the environment. Defaults to production.

 

@return string
*/
private function getEnvironment()
{
if (is_file($this->paths['env_file'])) {
Dotenv::load($this->paths['env_file_path']);
}
 
return getenv('ENVIRONMENT') ?: 'production';
}
}
{% endhighlight %}

As we notice, if the .env file is found in the project’s root directory, then we import its values
using the Dotenv class. The .env file looks like this:

{% highlight bash %}
ENVIRONMENT=local
{% endhighlight %}

If this file file is found, getenv('ENVIRONMENT') will return the value defined in the .env file.
If you wish to skip setting the .env file, you can define the environment in the web server configuration
(Apache, Nginx). But I wouldn’t
recommend it because the environment variables wouldn’t be available when your run a PHP script from the command line.

Getting configuration

After setting the actual configuration values
we initiate the Application class and we can finally read the the configuration files:

{% highlight php %}
<?php

// index.php

$app = new Application();

echo $app->config->get('app.db_username') . ' ' . $app->config->get('app.db_password');
{% endhighlight %}

Conclusion

Having a configuration feature in a project is very important as it makes it possible to run our app in different
environments and different settings.

In today’s tutorial we learned how to do that by using Laravel’s configuration class in projects independent from the laravel framework.
Of course the way of doing this is not unique! You are free to use illuminate/config the way it matches best to your application.

Other interesting reads