How to operate Symfony in a virtual folder

Problem:

I needed to run symfony in a virtual subfolder under an existing site, so that the asset URLs generate by helpers still originate from the root folder while URLs generated from routes contain the virtual subfolder. For example:

I have a site xyz.com that is run on some legacy platform that uses the same sort of layout for assets as symfony (stylesheets in /css, etc.). All the traffic for xyz.com goes through a load-balancer that splits off requests which URL starts with the prefix /symfonyApp and sends them to the server(s) running the symfony app. Symfony needs to generate asset URLs that look like /images/logo.gif while generating action URLs looking like /symfonyApp/signup/index.

Analysis:

The reason I was able to make this work at all is that the helper functions and the routing classes use different ways to insert the prefix folder name. Helpers get something called "RelativeUrlRoot" from the request object. This value can be set in factories.yml. Otherwise, it's calculated on demand by taking whatever is in front of the script file name in the SCRIPT_NAME environment variable.

Routes, on the other hand, store the prefix internally, though it's initialized to "RelativeUrlRoot + ScriptName", unless you override it in factories.yml.

Solution:

One solution would be to set the desired prefix values in factories.yml. But that requires duplicating the desired environment, which would be a pain to replicate. Instead, I opted to modify the values in the script file prior to dispatching the request. This way seems to work smoothly.

<?php

$tmp = dirname(__FILE__);
ini_set('error_log', $tmp . '/../../log/frontend_virtual_prod-error.log');

require_once($tmp.'/../../config/ProjectConfiguration.class.php');

$configuration = ProjectConfiguration::getApplicationConfiguration('frontend', 'prod', false);
$context = sfContext::createInstance($configuration);

// set separate prefixes for assets and links
$context->getRequest()->setRelativeUrlRoot(");
$routing = $context->getRouting();
$routingOptions = $routing->getOptions();
$routingOptions['context']['prefix'] = '/symfonyApp';
$routing->initialize($context->getEventDispatcher(), $routing->getCache(), $routingOptions);

$context->dispatch();

Leave a comment

Your comment