Each time the framework uses a path to look for something (from core classes to templates, plug-ins, configurations, and so on), it uses a path variable instead of an actual path. By changing these variables, you can completely alter the directory structure of a symfony project, and adapt to the file organization requirements of any client.
Caution Customizing the directory structure of a symfony project is possible but not necessarily a good idea. One of the strengths of a framework like symfony is that any web developer can look at a project built with it and feel at home, because of the respect for conventions. Make sure you consider this issue before deciding to use your own directory structure.
19.3.1. The Basic File Structure
The path variables are defined in the
$sf_symfony_data_dir/config/constants.php file, included when the application bootstraps. These variables are stored in the
sfConfig object, and so they are easy to override. Listing 19-3 shows a listing of the path variables and the directory they reference.
Listing 19-3 - Default File Structure Variables, from
sf_root_dir # myproject/ # apps/ sf_app_dir # myapp/ sf_app_config_dir # config/ sf_app_i18n_dir # i18n/ sf_app_lib_dir # lib/ sf_app_module_dir # modules/ sf_app_template_dir # templates/ sf_bin_dir # batch/ # cache/ sf_base_cache_dir # myapp/ sf_cache_dir # prod/ sf_template_cache_dir # templates/ sf_i18n_cache_dir # i18n/ sf_config_cache_dir # config/ sf_test_cache_dir # test/ sf_module_cache_dir # modules/ sf_config_dir # config/ sf_data_dir # data/ sf_doc_dir # doc/ sf_lib_dir # lib/ sf_model_lib_dir # model/ sf_log_dir # log/ sf_test_dir # test/ sf_plugins_dir # plugins/ sf_web_dir # web/ sf_upload_dir # uploads/
Every path to a key directory is determined by a parameter ending with
_dir. Always use the path variables instead of real (relative or absolute) file paths, so that you will be able to change them later, if necessary. For instance, when you want to move a file to the
uploads/ directory in an application, you should use
sfConfig::get('sf_upload_dir') for the path instead of
The module directory structure is defined at runtime, when the routing system determines the module name (
$module_name). It is automatically built according to the path names defined in the
constants.php file, as shown in Listing 19-4.
Listing 19-4 - Default Module File Structure Variables
sf_app_module_dir # modules/ module_name # mymodule/ sf_app_module_action_dir_name # actions/ sf_app_module_template_dir_name # templates/ sf_app_module_lib_dir_name # lib/ sf_app_module_view_dir_name # views/ sf_app_module_validate_dir_name # validate/ sf_app_module_config_dir_name # config/ sf_app_module_i18n_dir_name # i18n/
So, for instance, the path to the
validate/ directory of the current module is built dynamically at runtime:
19.3.2. Customizing the File Structure
You will probably need to modify the default project file structure if you develop an application for a client who already has a defined directory structure and who is not willing to change it to comply with the symfony logic. By overriding the
sf_XXX_dir_name variables with
sfConfig, you can make symfony work for a totally different directory structure than the default structure. The best place to do this is in the application
Caution Use the application
config.php and not the project one to override the
sf_XXX_dir_name variables with
sfConfig. The project
config/config.php file is loaded very early in the life of a request, at a time when the
sfConfig class doesn't exist yet, and when the
constants.php file is not yet loaded.
For instance, if you want all applications to share a common directory for the template layouts, add this line to the
myapp/config/config.php file to override the
Note that the application config.php file is not empty, so if you need to include file structure definitions there, do it at the end of the file.
19.3.3. Modifying the Project Web Root
All the paths built in
constants.php rely on the project root directory, which is a constant defined in the front controller (
SF_ROOT_DIR). Usually, the root directory is one level above the
web/ directory, but you can use a different structure. Suppose that your main directory structure is made of two directories, one public and one private, as shown in Listing 19-5. This typically happens when hosting a project on a shared host.
Listing 19-5 - Example of Custom Directory Structure for a Shared Host
symfony/ # Private area apps/ batch/ cache/ ... www/ # Public area images/ css/ js/ index.php
In this case, the root directory is the
symfony/ directory. So the
index.php front controller simply needs to define the
SF_ROOT_DIR as follows for the application to work:
In addition, since the public area is
www/ instead of the usual
web/, you must override two file paths in the application
config.php file, as follows:
sfConfig::add(array( 'sf_web_dir' => SF_ROOT_DIR.'/../www', 'sf_upload_dir' => SF_ROOT_DIR.'/../www/'.sfConfig::get('sf_upload_dir_name'), ));
19.3.4. Linking to Symfony Libraries
The paths to the framework files are defined in the project
config.php file, as you can see in Listing 19-6.
Listing 19-6 - The Paths to the Framework Files, in
// symfony directories $sf_symfony_lib_dir = '/path/to/symfony/lib'; $sf_symfony_data_dir = '/path/to/symfony/data';
These paths are initialized when you call a
symfony init-project from the command line, and refer to the symfony installation used to build the project. They are used both by the command line and by the MVC architecture.
This means that you can switch to another installation of symfony by changing the paths to the framework files.
These paths should be absolute, but by using
dirname(__FILE__), you can refer to files inside the project structure and preserve independence of the chosen directory for the project installation. For instance, many projects choose to have the symfony
lib/ directory appear as a symbolic link in the project
lib/symfony/ directory, and do the same for the symfony
data/ directory, as follows:
myproject/ lib/ symfony/ => /path/to/symfony/lib data/ symfony/ => /path/to/symfony/data
In this case, the project config.php file just needs to define the symfony directories as follows:
$sf_symfony_lib_dir = dirname(__FILE__).'/../lib/symfony'; $sf_symfony_data_dir = dirname(__FILE__).'/../data/symfony';
The same principle also applies if you choose to include the symfony files as a
svn:externals in the project
myproject/ lib/ vendor/ svn:externals symfony http://svn.symfony-project.com/branches/1.0
In this case, the
config.php file should look like this:
$sf_symfony_lib_dir = dirname(__FILE__).'/../lib/vendor/symfony/lib'; $sf_symfony_data_dir = dirname(__FILE__).'/../lib/vendor/symfony/data';
Tip Sometimes, the different servers running an application don't have the same path to the symfony libraries. One way to enable that is to exclude the project
config.php file from the synchronization (by adding it to
rsync_exclude.txt). Another method is to keep the same paths in the development and production versions of
config.php, but to have these paths point to symbolic links that can vary according to the server.