There are a number of ways to set environment variables in PHP. But the approach I use most often in development is a wonderful package called PHP dotenv. In this tutorial, I’m going to step you through how to install and use it.
Before we dive right on in, why would you set and use environment variables anyway? Why wouldn’t you just store credentials in your code, where you can see and quickly edit them?
Honestly? Because you should never store credentials or any form of sensitive data in your code. Ever! Among others, here are two key reasons.
Firstly, if anyone ever gets access to your source code, whether that be a malicious actor or a disgruntled former co-worker, etc, they have access to secret keys, API keys, usernames, passwords – everything. Given that, they can make authenticated requests and no one would be any the wiser.
I’m not trying to say that people are out to get you, or that you should be paranoid. However, there are people who, for a wide number of reasons, look for the opportunity to do malicious things. By storing secure credentials and sensitive data in your code, you’re making it pretty easy for them to do so. All it would take is an accidental server misconfiguration or a security breach and the secure data is available for all the world to see.
What’s more, if you put these credentials in your code, and you’re using version control, then they’re also stored there too. Yes, you can purge information from Git repositories that never should have been there, but it’s best to never put that kind of secure data under version control in the first place.
Secondly, if secure credentials are stored directly in your code, then every deployment must use them. Think about:
By having code set in environment variables, the credentials are kept out of the code. And by having secure credentials and other details retrieved from environment variables:
What other benefits can you think of? Let me know in the comments, or tweet me. Otherwise, let’s get in and write some code so you can see what I mean.
To following along with this tutorial, you’re going to need the following:
PHP dotenv is, conceptually, quite simple.
By default, it loads environment variables from a file named .env making them available to the
getenv() method, and loads them in to
It does more than that, as you’ll see shortly, but for now that’s the essence of what it does.
For the purposes of this tutorial, let’s say that your code needs an API key to make authenticated requests, such as to SendGrid or Twilio.
The code will retrieve it from PHP’s $_SERVER superglobal using the key
API_KEY, after PHP dotenv loads it there.
Thanks to Composer, there’s virtually nothing you need to install PHP dotenv, other than running the following command.
composer require vlucas/phpdotenv
In the top-level directory of your project, create a new file named .env. In it add the configuration below.
It’s a very strong API key, no? But seriously, set it to whatever you want. It’s not important for the purposes of this tutorial.
Next, have PHP dotenv load API_KEY read .env and load the environment variables – as early in the lifecycle of your application as possible. To do that, add the following code to the top of your application’s main file, likely public/index.php, right after it includes Composer’s autoloader, as in the example below.
require __DIR__ . '/vendor/autoload.php'; $dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/'); $dotenv->load(); ...
This way, your application’s code will always have access to the API key.
Now, all you need to do is to reference either
$_SERVER['API_KEY'] in your application, when you need to reference the API key.
One way that I’ve become fond of when working with Mezzio, is to set the relevant configuration variables, which are stored in the DI (Dependency Injection) Container, from
$_SERVER, and then use those configuration variables, as in the following example.
<?php return [ 'service' => [ 'api_key' => $_SERVER['API_KEY'] ] ];
I find it simpler and it’s analagous to what other frameworks, such as Laravel and Symfony do.
By default, PHP dotenv will look for a dotenv file named .env in the directory passed to
However, you may prefer to name the file differently, for whatever reason.
To use a different name or supply a range of potential file names, supply them as the second parameter to
createImmutable(), as in the example below.
// Use a different file name $dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/', '.dotenv'); // Supply a range of file names to use $dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/', ['.dotenv', '.dot_env']);
Another helpful thing you can do is require one or more environment variables to be set.
I find this to be a good way to provide a documented list of all the environment variables which an application needs.
To do this, use the
required() method, as in the following example.
require __DIR__ . '/vendor/autoload.php'; $dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/'); $dotenv->load(); $dotenv->required([ 'API_KEY', ]); ...
API_KEY is not set in the dotenv file, PHP dotenv will throw an exception.
You can take this further by also requiring the variable to not be empty, as in the example below.
require __DIR__ . '/vendor/autoload.php'; $dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/'); $dotenv->load(); $dotenv->required([ 'API_KEY', ])->notEmpty(); ...
I hope that this short tutorial’s shown you both why it’s a good idea to keep secure credentials out of code, and how to do it, using PHP dotenv. If you’d like to learn several other ways of working with environment variables in PHP, check out this tutorial that I wrote.
Otherwise, have a play with PHP dotenv and the other functionality it has to offer. If you already use it, what’s your experience been with it?
Join the discussioncomments powered by Disqus