Buy

Question: if config.yml is so important - then what the heck is the point of all of these other files - like config_dev.yml, config_test.yml, parameters.yml, security.yml and services.yml. What is their purpose?

What is an Environment?

The answer is environments. Now, I don't mean environments like dev, staging, or production on your servers. In Symfony, an environment is a set of configuration. Environments are also one of its most powerful features.

Think about it: an application is a big collection of code. But to get that code running it needs configuration. It needs to know what your database password is, what file your logger should write to, and at what priority of messages it should bother logging.

The dev and prod Environments

Symfony has two environments by default: dev and prod. In the dev environment your code is booted with a lot of logging and debugging tools. But in the prod environment, that same code is booted with minimal logging and other configuration that makes everything fast.

Tip

Actually, there's a third environment called test that you might use while writing automated tests.

So.... how do we choose which environment we're using? And what environment have we been using so far?

app.php versus app_dev.php

The answer to that lives in the web directory, which is the document root. This is the only directory whose files can be accessed publicly.

These two files - app.php and app_dev.php - are the keys. When you visit your app, you're always executing one of these files. Since we're using the server:run built-in web server: we're executing app_dev.php:

33 lines web/app_dev.php
... lines 1 - 2
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Debug\Debug;
// If you don't want to setup permissions the proper way, just uncomment the following PHP line
// read http://symfony.com/doc/current/book/installation.html#checking-symfony-application-configuration-and-setup
// for more information
//umask(0000);
// This check prevents access to debug front controllers that are deployed by accident to production servers.
// Feel free to remove this, extend it, or make something more sophisticated.
if (isset($_SERVER['HTTP_CLIENT_IP'])
|| isset($_SERVER['HTTP_X_FORWARDED_FOR'])
|| !(in_array(@$_SERVER['REMOTE_ADDR'], array('127.0.0.1', 'fe80::1', '::1')) || php_sapi_name() === 'cli-server')
) {
header('HTTP/1.0 403 Forbidden');
exit('You are not allowed to access this file. Check '.basename(__FILE__).' for more information.');
}
/**
* @var Composer\Autoload\ClassLoader $loader
*/
$loader = require __DIR__.'/../app/autoload.php';
Debug::enable();
$kernel = new AppKernel('dev', true);
$kernel->loadClassCache();
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);

The web server is preconfigured to hit this file.

That means that when we go to localhost:8000/genus/octopus that's equivalent to going to localhost:8000/app_dev.php/genus/octopus. With that URL, the page still loads exactly like before.

So how can we switch to the prod environment? Just copy that URL and change app_dev.php to app.php. Welcome to the prod environment: same app, but no web debug toolbar or other dev tools:

33 lines web/app.php
... lines 1 - 2
use Symfony\Component\HttpFoundation\Request;
/**
* @var Composer\Autoload\ClassLoader
*/
$loader = require __DIR__.'/../app/autoload.php';
include_once __DIR__.'/../var/bootstrap.php.cache';
// Enable APC for autoloading to improve performance.
// You should change the ApcClassLoader first argument to a unique prefix
// in order to prevent cache key conflicts with other applications
// also using APC.
/*
$apcLoader = new Symfony\Component\ClassLoader\ApcClassLoader(sha1(__FILE__), $loader);
$loader->unregister();
$apcLoader->register(true);
*/
//require_once __DIR__.'/../app/AppCache.php';
$kernel = new AppKernel('prod', false);
$kernel->loadClassCache();
//$kernel = new AppCache($kernel);
// When using the HttpCache, you need to call the method in your front controller instead of relying on the configuration parameter
//Request::enableHttpMethodParameterOverride();
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);

This baby is optimized for speed.

But don't worry: in production you won't have this ugly app.php in your URL: you'll configure your web server to execute that file when nothing appears in the URL.

So this is how you "choose" your environment. And other than on your production server, you'll pretty much always want to be in the dev environment.

But the real fun starts next: when we learn how to bend and optimize each environment exactly to our needs.

Leave a comment!

  • 2016-06-14 weaverryan

    And it seems I jumped the gun and replied to your other comment before I saw this one ;). No harm done - it'll help others I'm sure!

  • 2016-06-13 JLChafardet

    seems I jumped the gun on the previous chapter as the environments were touched briefly here.