Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine
This tutorial has a new version, check it out!

Environments

Keep on Learning!

If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

Start your All-Access Pass
Buy just this tutorial for $12.00

With a Subscription, click any sentence in the script to jump to that part of the video!

Login Subscribe

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!

10
Login or Register to join the conversation
Default user avatar

Hi, does anyone have any idea why accessing the prod link (with app.php, not app_dev.php) returns a 404?
I'm using Homestead VM on Windows instead of serving the app locally. Tried with bin/console cache:clear --env=prod already, but it doesn't make any difference.

Reply

Hey Marko!

Hmmm. So first, let's try to figure out if the 404 is coming from Symfony (meaning Symfony is running, but it is not finding any route) or if it's coming from somewhere else (e.g. Nginx, because it can't find/execute app.php). If the error looks something like this - https://samsonasik.files.wo... - that *is* coming from Symfony... and for some reason, there is no route found. Let me know, this would indeed be weird, since you have already thought of clearing the cache :). If the error looks different, it might be some other issue.

Cheers!

Reply
Default user avatar

Hi Ryan, sorry for forgetting to include that piece of info, the 404 is actually coming from nginx. Thanks for the quick response! :)

Reply

Hey Marko,

Hm, could you double check your virtual host configuration? Is your document root path is valid? Does it point to web/ directory of your Symfony project? Do you have app.php file in this web/ folder? See https://symfony.com/doc/cur... for more instructions for Nginx web server.

Btw, when you do not specify app.php in the URL it works? I mean, both URLs: http://your-domain.example.... and http://your-domain.example.... does not work for you or only the 2nd one?

Cheers!

Reply
Default user avatar

Hi Victor,

yes, the document root is /web, and app.php file exists. The official Symfony docs states that the only thing that needs to be added to the Homestead.yaml is type: symfony
http://symfony.com/doc/curr...
and this is my configuration in the Homestead.yaml file
folders:
- map: C:/Users/marko/code
to: /home/vagrant/code
type: "nfs"

sites:
- map: symfony.app
to: /home/vagrant/code/aqua_note/web
type: symfony
Yes, it only doesn't work with app.php in the URL, but if I put app_dev.php or leave it out completely, everything works normal.

Here's the sites' nginx configuration from Homestead
https://pastebin.com/gt61mNsb

Thanks!

Reply

Hey Marko,

Ah, that's easy win - just comment out "internal;" line, it prevents calling /app.php directly... which is exactly what you want in production btw, so I'd not recommend you allowing it :)

P.S. I haven't used Homestead, so don't know whether there an option for that in their config file.

Cheers!

Reply
Default user avatar
Default user avatar Claudio | posted 5 years ago

Hey!

When I change the URL from app_dev.php to app.php I get an error :O
The server returned a "500 Internal Server Error".

Well, with app_dev.php I have no problems but this app.php thing might be problematic issue in the future.
Do you know maybe what is making this error in the prod environment?

cheers!

Reply

Hey Claudio!

This is actually totally normal :). And we talk a bit more about why a few chapters from now: https://knpuniversity.com/s...

Basically, when you use the "prod" environment (app.php), Symfony does not rebuild any of its cached files. That means that if you edited a route and used app.php, Symfony would try to use the old (cached) route configuration. Often, you've made *so* many changes to configuration, that when you use app.php, the cache is so outdated that it causes the application to error out like this. But, like I said, that's totally normal: you will always clear your cache (bin/console cache:clear --env=prod) before switching to the prod environment. This becomes part of your deploy process: move the files to your server, then clear the prod cache. When you clear the cache, you won't have any errors :).

But, btw, if you *do* ever have a 500 Internal Server Error in the future (these can happen on production if you have a bug in your code!) you can see the error information by looking at your var/logs/prod.log file.

Cheers!

1 Reply

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

Reply

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!

1 Reply
Cat in space

"Houston: no signs of life"
Start the conversation!

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": ">=5.5.9",
        "symfony/symfony": "3.1.*", // v3.1.4
        "doctrine/orm": "^2.5", // v2.7.2
        "doctrine/doctrine-bundle": "^1.6", // 1.6.4
        "doctrine/doctrine-cache-bundle": "^1.2", // 1.3.0
        "symfony/swiftmailer-bundle": "^2.3", // v2.3.11
        "symfony/monolog-bundle": "^2.8", // 2.11.1
        "symfony/polyfill-apcu": "^1.0", // v1.2.0
        "sensio/distribution-bundle": "^5.0", // v5.0.22
        "sensio/framework-extra-bundle": "^3.0.2", // v3.0.16
        "incenteev/composer-parameter-handler": "^2.0", // v2.1.2
        "composer/package-versions-deprecated": "^1.11", // 1.11.99
        "knplabs/knp-markdown-bundle": "^1.4" // 1.4.2
    },
    "require-dev": {
        "sensio/generator-bundle": "^3.0", // v3.0.7
        "symfony/phpunit-bridge": "^3.0" // v3.1.3
    }
}
userVoice