Symfony : méfiez-vous des chemins relatifs

Il se trouve que le client pour lequel j’ai travaillé a une configuration d’Apache un peu particulière, qui est constituée de 2 Apaches avec du reverse proxy et tutti quanti.

Du coup, le site Symfony n’a pas son propre virtualhost exposé directement sur le Web : on ne tape pas http://monsitesymfony.com pour y accéder mais http://apps.monentreprise.com/monsitesymfony/, car ils mutualisent leurs applications.

Conséquence : deux ou trois choses ne fonctionnaient pas du 1er coup concernant les uploads et prévisualisation des fichiers uploadés ou encore l’image d’un datepicker.

Pour s’affranchir de ce genre de problème, je vous conseille de toujours faire un passe de test sans utiliser le virtualhost, mais plutôt http://votreserveur/votresite/web/, de façon à détecter ce genre de problème.

Le problème vient du fait qu’avec un virtualhost, les chemins absolus genre « /image/calendar.png » fonctionnent => http://monsitesymfony.com/image/calendar.png

Si vous avec un sous-répertoire : « /image/calendar.png » => http://apps.monentreprise.com/image/calendar.png : il manque le « /monsitesymfony/ ».

Pour parer à ce genre de problème, un peu tordu je l’admets, il vous faut une fonction comme suite :

/**
* @return string La partie du l'URL après le nom du serveur et avant le nom du script PHP.
* Exemple : http://www.serveur.com/monsite/index.php/... => retourne monsite/
*/
public static function getBaseURL()
{
return sfConfig::get('sf_relative_url_root', preg_replace('#/[^/]+\.php5?$#', '', isset($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME'] : (isset($_SERVER['ORIG_SCRIPT_NAME']) ? $_SERVER['ORIG_SCRIPT_NAME'] : '')));
}

Exemple :

Pour une image de datepicker avec un JqueryDatePicker par exemple, il faut passer aux options du widget le chemin de l’image construit avec le préfixe :

'image'         => MaClasse::getBaseURL() . '/images/pictos/calendar.png'

Pour les uploads c’est la même chose, on a souvent besoin du chemin absolu et de l’URL de prévisu, il faut également utiliser le getBaseURL() pour préfixer les URL correctement.

Je ne suis pas rentré dans les détails, je voulais juste vous faire partage un point sur lequel il faut être attentif.