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 namedCodeship
.
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.