Symfony4 applications by default use .env file for application variables. In this example we are going to let our application to dynamically use .env.test file when we access it from the browser and terminal command. In order to do that we have to implement changes below.


Files


config/packages/doctrine.yaml


This file gets created automatically when we run composer require doctrine.


parameters:
env(DATABASE_URL): ''

doctrine:
dbal:
driver: 'pdo_mysql'
server_version: '5.7'
charset: utf8mb4
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci

url: '%env(resolve:DATABASE_URL)%'
orm:
auto_generate_proxy_classes: '%kernel.debug%'
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: true
mappings:
App:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: App

config/packages/test/doctrine.yaml


Create this file. You can find the version by running $ sqlite3 --version command.


doctrine:
dbal:
driver: 'pdo_sqlite'
server_version: '3.11.0'

bin/console


Add code below right above $kernel = new Kernel($env, $debug);.


if ($env === 'test') {
(new Dotenv())->load(__DIR__.'/../.env.test');
}

public/index_test.php


Copy the content of public/index.php and create this file then do the following changes.


# Replace
$env = $_SERVER['APP_ENV'] ?? 'dev';
# with
$env = 'test';

# Add line below right above $kernel = new Kernel($env, $debug);
(new Dotenv())->load(__DIR__.'/../.env.test');

.env


This file exists and represents the dev environment.


###> symfony/framework-bundle ###
APP_ENV=dev
APP_SECRET=d7f88292186a64eeef558337bb2f0f43
###< symfony/framework-bundle ###

###> doctrine/doctrine-bundle ###
DATABASE_URL=mysql://root:root@127.0.0.1:3306/symfony
###< doctrine/doctrine-bundle ###

.env.test


Create this file.


###> symfony/framework-bundle ###
APP_ENV=test
APP_SECRET=d7f88292186a64eeef558337bb2f0f43
###< symfony/framework-bundle ###

###> doctrine/doctrine-bundle ###
DATABASE_URL=sqlite:///%kernel.project_dir%/var/cache/test/database.db
###< doctrine/doctrine-bundle ###

Nginx configuration


server {
listen 80;

server_name symfony-4-0-skeleton.dev;

root /srv/www/symfony/4-0-skeleton/public;

location / {
try_files $uri /index.php$is_args$args;
}

# REMOVE THIS WHOLE BLOCK IN PRODUCTION
location ~ ^/index_test\.php(/|$) {
fastcgi_pass unix:/run/php/php7.2-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
}

location ~ ^/index\.php(/|$) {
fastcgi_pass unix:/run/php/php7.2-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
internal;
}

location ~ \.php$ {
return 404;
}

error_log /var/log/nginx/symfony_4_0_skeleton_error.log;
access_log /var/log/nginx/symfony_4_0_skeleton_access.log;
}

Test


If you go to http://192.168.99.30 it would use .env file with MySQL database. However, if you go to http://192.168.99.30/index_test.php it would use .env.test file with SQLite database. Same applies applies to terminal commands where we use ... -env=test flag.