- 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
- How to integrate Elasticsearch in your Laravel App – 2021
- Let’s have pessimistic locking strategies
- Using MySQL for Testing (on Laravel)
- HTTP Client for SDKs
- Improving code style when working on a legacy code base
- Laravel IoC container
- Integrating Elasticsearch with Your Laravel app
- Laravel 5 Command-Oriented Approach
Member discussion