Upgrading Existing Applications to Symfony Flex

Using Symfony Flex is optional, even in Symfony 4, where Flex is used bydefault. However, Flex is so convenient and improves your productivity so muchthat it's strongly recommended to upgrade your existing applications to it.

Symfony Flex recommends that applications use the following directory structure,which is the same used by default in Symfony 4, but you cancustomize some directories:

  1. your-project/
  2. ├── assets/
  3. ├── bin/
  4. └── console
  5. ├── config/
  6. ├── bundles.php
  7. ├── packages/
  8. ├── routes.yaml
  9. └── services.yaml
  10. ├── public/
  11. └── index.php
  12. ├── src/
  13. ├── ...
  14. └── Kernel.php
  15. ├── templates/
  16. ├── tests/
  17. ├── translations/
  18. ├── var/
  19. └── vendor/

This means that installing the symfony/flex dependency in your applicationis not enough. You must also upgrade the directory structure to the one shownabove. There's no automatic tool to make this upgrade, so you must follow thesemanual steps:

  • Install Flex as a dependency of your project:
  1. $ composer require symfony/flex
  • If the project's composer.json file contains symfony/symfony dependency,it still depends on the Symfony Standard Edition, which is no longer availablein Symfony 4. First, remove this dependency:
  1. $ composer remove symfony/symfony

Now add the symfony/symfony package to the conflict section of the project'scomposer.json file as shown in this example of the skeleton-project so thatit will not be installed again:

  1. {
  2. "require": {
  3. "symfony/flex": "^1.0",
  4. + },
  5. + "conflict": {
  6. + "symfony/symfony": "*"
  7. }
  8. }

Now you must add in composer.json all the Symfony dependencies requiredby your project. A quick way to do that is to add all the components thatwere included in the previous symfony/symfony dependency and later youcan remove anything you don't really need:

  1. $ composer require annotations asset orm-pack twig \
  2. logger mailer form security translation validator
  3. $ composer require --dev dotenv maker-bundle orm-fixtures profiler
  • If the project's composer.json file doesn't contain the symfony/symfonydependency, it already defines its dependencies explicitly, as required byFlex. Reinstall all dependencies to force Flex to generate theconfiguration files in config/, which is the most tedious part of the upgradeprocess:
  1. $ rm -rf vendor/*
  2. $ composer install
  • No matter which of the previous steps you followed. At this point, you'll havelots of new config files in config/. They contain the default configdefined by Symfony, so you must check your original files in app/config/and make the needed changes in the new files. Flex config doesn't use suffixesin config files, so the old app/config/config_dev.yml goes toconfig/packages/dev/*.yaml, etc.

  • The most important config file is app/config/services.yml, which now islocated at config/services.yaml. Copy the contents of thedefault services.yaml file and then add your own service configuration.Later you can revisit this file because thanks to Symfony'sautowiring feature you can removemost of the service configuration.

Note

Make sure that your previous configuration files don't have importsdeclarations pointing to resources already loaded by Kernel::configureContainer()or Kernel::configureRoutes() methods.

  • Move the rest of the app/ contents as follows (and after that, remove theapp/ directory):

    • app/Resources/views/ -> templates/
    • app/Resources/translations/ -> translations/
    • app/Resources/<BundleName>/views/ -> templates/bundles/<BundleName>/
    • rest of app/Resources/ files -> src/Resources/
  • Move the original PHP source code from src/AppBundle/*, except bundlespecific files (like AppBundle.php and DependencyInjection/), tosrc/.

In addition to moving the files, update the autoload and autoload-devvalues of the composer.json file as shown in this example to useApp\ and App\Tests\ as the application namespaces (advanced IDEs cando this automatically).

If you used multiple bundles to organize your code, you must reorganize yourcode into src/. For example, if you had src/UserBundle/Controller/DefaultController.phpand src/ProductBundle/Controller/DefaultController.php, you could movethem to src/Controller/UserController.php and src/Controller/ProductController.php.

  • Move the public assets, such as images or compiled CSS/JS files, fromsrc/AppBundle/Resources/public/ to public/ (e.g. public/images/).

  • Move the source of the assets (e.g. the SCSS files) to assets/ and useWebpack Encore to manage and compile them.

  • SYMFONY_DEBUG and SYMFONY_ENV environment variables were replaced byAPP_DEBUG and APP_ENV. Copy their values to the new vars and then removethe former ones.

  • Create the new public/index.php front controllercopying Symfony's index.php source and, if you made any customization inyour web/app.php and web/app_dev.php files, copy those changes intothe new file. You can now remove the old web/ dir.

  • Update the bin/console script copying Symfony's bin/console sourceand changing anything according to your original console script.

  • Remove src/AppBundle/.

  • Move the original source code from src/{App,…}Bundle/ to src/ andupdate the namespaces of every PHP file to be App... (advanced IDEs can dothis automatically).

  • Remove the bin/symfony_requirements script and if you need a replacementfor it, use the new Symfony Requirements Checker.

  • Update the .gitignore file to replace the existing var/logs/ entryby var/log/, which is the new name for the log directory.

Customizing Flex Paths

The Flex recipes make a few assumptions about your project's directory structure.Some of these assumptions can be customized by adding a key under the extrasection of your composer.json file. For example, to tell Flex to copy anyPHP classes into src/App instead of src:

  1. {
  2. "...": "...",
  3.  
  4. "extra": {
  5. "src-dir": "src/App"
  6. }
  7. }

The configurable paths are:

  • bin-dir: defaults to bin/
  • config-dir: defaults to config/
  • src-dir defaults to src/
  • var-dir defaults to var/
  • public-dir defaults to public/If you customize these paths, some files copied from a recipe still may containreferences to the original path. In other words: you may need to update some thingsmanually after a recipe is installed.