Read Environment Variables in Appropriate PHP Type

Written by: João Cercal

You probably get your environment variables using built-in PHP functions such as getenv or $_ENV. But did you know that you can do it in an elegant way, getting an environment variable's value in the proper PHP data type with a powerful library? If you're curious, read on about how this energetic library can help you in your daily development workflow.

Throughout this article, we'll be using the vlucas/phpdotenv library to load environment variables from an external file.

Installing Dependencies with the vlucas/phpdotenv Library

First, you need to install the dependencies. Simply type this in your terminal:

$ composer require vlucas/phpdotenv
$ composer require cekurte/environment

Now, we need to create a .env file and put the first environment variable in it.

$ touch .env
$ echo "PHP_DEBUG=true" > .env

Let's read the environment variable and dump this value to the screen.

load();
var_dump(Environment::get("PHP_DEBUG"));
// If you run this code, you'll see like a magic:
// bool(true)

Did you see that the data type of this value is a bool and not a string? Cool, but it could be better.

Let's move on to the next step and explore more features.

Saving Configurations as an Array

What do you think of saving your configurations in a unique environment variable as an array? That sounds good, at least for some occasions:

$ echo "NUMBERS=[0,2,4,6,8]" >> .env
 int(0)
// [1]=> int(2)
// [2]=> int(4)
// [3]=> int(6)
// [4]=> int(8)
// }

Good one. Did you see that you can define complex data structures to your environment variables?

If you want, you can read the documentation of cekurte/environment to understand how many data types you can use there, with examples and details about what the library supports.

Coding a Real Application

In the next section, we will code a real application that uses the same concept shown below to get configurations. We'll do it creating a wrapper to rclone.

Well, we'll use Rclone to connect on Amazon Cloud Drive and list every file from there in a specific folder. Feel free to implement wherever you want of this idea. For example, maybe upload your files to your Amazon Cloud Drive, perhaps files like database backups.

What is Rclone?

Rclone is a command-line program that can be used to synchronize the files from a source to a target. It supports some providers like:

  • Google Drive

  • Amazon S3

  • Dropbox

  • Google Cloud Storage

  • Amazon Drive

  • Microsoft OneDrive

  • SFTP

  • The local filesystem

To see the complete list of supported providers, please read more on Rclone's homepage.

How to install rclone on your machine

Follow the official documentation that will explain how to install Rclone on your machine (it works on Windows, Linux, and OS X, so don't worry). If you want to install it on your server, yes, you can do that without any problems.

How to configure Rclone

You will need to configure Rlone to any cloud providers that you want to use with it. In this case, we will just configure the Amazon Cloud Drive account.

Before moving on, be sure that you have Rclone on your PATH operating system variable and run the following command to configure Rclone to manage files of your cloud drive:

$ rclone config

You will be asked about an alias. As a convention to this tutorial, I'm supposing that we are using the alias amazon, and you have a specific folder in the root directory named Codeship.

Fill the information according to the questions. After that, when you run this command, you will see all the files of your cloud root folder:

# rclone ls your-alias:/
rclone ls amazon:/Codeship

This command will print to the console every file that's there on the Codeship folder of your Amazon Cloud Drive. If it's working, let's move on.

!Sign up for a free Codeship Account

Creating Our PHP Project

We will follow a few steps to get our application working. If you have any doubt about any of the steps, please leave a comment or send me a message directly. I'd love talk with you about it.

The dependency manager

Composer is the dependency manager tool that we'll use. Let’s create a new PHP project and import a few dependencies using Composer.

When you enter the first command composer init, you will be asked about the configurations of your new project.

$ composer init
$ composer require vlucas/phpdotenv
$ composer require cekurte/environment
$ composer require symfony/process
$ composer require symfony/console

There's more one thing to finish with the composer configuration. We need to say what is the namespace of our application. To do this, add an autoload field to the composer.json file like this:

{
    "autoload": {
        "psr-4": {"App\\": "src/"}
    }
}

Composer will register a PSR-4 autoloader for the App namespace.

Creating our environment variables

Our environment variables will keep the configurations of our command-line application. Here is the point where you can change the path to rclone binary, for example, or change the configuration of anything that you are seeing above.

Let's create the environment variable file .env in the root folder of our project and fill it with some useful configs for the scope of this application.

$ touch .env
$ echo "CLOUD_PROVIDER={'alias': 'amazon', 'directory': '/CodeShip'}" > .env
$ echo "RCLONE_BIN=/usr/bin/rclone" >> .env

That's it. The CLOUD_PROVIDER has json content, and it will be used to retrieve the information about your specific configuration that we did in rclone config.

The RCLONE_BIN has a string that will point to the binary installation path of the rclone tool on your machine. Also, the RCLONE_DEFAULT_ARGS has an array that will be used to send Rclone commands with these default arguments.

The ListCommand

The ListCommand will be the class responsible to list all files that are inside of our Codeship folder on Amazon Cloud Drive. First, create the src directory in your project folder. Inside it, create the ListCommand.php file.

$ mkdir src
$ touch src/ListCommand.php

The content of ListCommand.php will be:

setName('app:list')
            ->setDescription('List the content of your remote folder.')
            ->setHelp('This command will list every file that´s inside of your cloud drive folder.')
        ;
    }
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $io = new SymfonyStyle($input, $output);
        $cloudProvider = Environment::get('CLOUD_PROVIDER');
        $io->section(sprintf(
            'Listing files from "%s:%s".',
            $cloudProvider['alias'],
            $cloudProvider['directory']
        ));
        $builder = new ProcessBuilder();
        $builder->setPrefix(sprintf(
            "%s ls %s:%s",
            Environment::get('RCLONE_BIN'),
            $cloudProvider['alias'],
            $cloudProvider['directory']
        ));
        $process = $builder
            ->setArguments(Environment::get('RCLONE_DEFAULT_PARAMS'))
            ->getProcess()
            ->setTimeout(3600)
            ->setIdleTimeout(60)
        ;
        $process->start();
        $process->wait(function ($type, $buffer) use ($io) {
            if (Process::ERR === $type) {
                $io->error($buffer);
            } else {
                $io->text($buffer);
            }
        });
    }
}

How to run this command-line application

The last thing that we need to do is create an entry-point file (our main function).

$ touch app.php

Fill this file with the following content:

#!/usr/bin/env php
load();
$application = new Application();
$application->setName('RClone Wrapper');
$application->setVersion('v1.0');
$application->add(new ListCommand());
$application->run();

To run this application, just type it in your terminal:

php app.php

If you have any files on the folder Codeship in your Amazon Cloud Drive, those files will be listed on your console.

Yes, I know it's really simple, but I wanted to share how you can use environment variables in your project. Why not think about complex data values?

Conclusion

As you can see, we can use environment variables to do a lot of things. You can increase the quality of your work just putting the configuration on environment variables to change the behavior of a component in your application flow without changing even a line of your source code.

You don't need to convert your types; you just need to use this feature of a library to improve your performance and make your code easier to read and understand.

Let me know if you have problems following this step-by-step tutorial and how or when you are thinking of using this feature on your next project.

A unique restriction that I can see with using environment variables is to set your database/API credentials, so be careful about that.

Stay up-to-date with the latest insights

Sign up today for the CloudBees newsletter and get our latest and greatest how-to’s and developer insights, product updates and company news!