The purpose of this post

If you work on a Silex project once in a while, you’ve probably noticed there’s a new major version available.

The official upgrade guide was short and didn’t really help me tackle every issue. So in this post I’ll share the steps I had to take to upgrade my code to hopefully save you some time.

1. Check your PHP version!

PHP 5.5/7.0+ is required. If your development environment and/or servers don’t run these versions, update them first.

2. Remove old Silex

The easiest way I’ve found to upgrade Composer components to new major releases is to remove the old component and require the new one, like so:

composer remove silex/silex
composer require silex/silex

Composer doesn’t automatically update major releases that require code changes (e.g. 1.x.x to 2.x.x). Which is very convenient if you don’t want to accidentally break your application. If you don’t choose the route above, this means you will have to upgrade every component that requires a new major version.

3. Install Silex 2.x

composer require silex/silex
composer update --with-dependencies

This actually updates Silex 2.x and its dependencies. For me this resulted in 26 updated components.

You may get the following message: Your requirements could not be resolved to an installable set of packages. This probably means that one of your components is not compatible with some newly installed component versions (version conflict). In my case I’ve found the easiest way is to remove the component and resolve the conflict after upgrading Silex.

composer remove [name of conflicting component]

4. Check if other components are out of date

While you’re at it, check if there are other components in your package.json that could use an upgrade.

composer outdated

In my case I found 2 components that could be updated. For each component:

composer remove [name of component]
composer require [name of component]

5. See if it runs..

In my case I didn’t know if I had to change any code, so I just tried to run it and go through the errors one by one. Which resulted in:

Fatal error: Call to undefined method Silex\Application::share()
(...)

Too bad.

6. Solve issues

In the next sections I’ll go through the issues that I had to solve in my case and how I did it. If you’re not using the mentioned component, skip that section.

Translations

The error message above is related to Shared services, for which the syntax has changed.

Old code:

<?php
// (...)
$app['translator'] = $app->share($app->extend('translator', function($translator, $app) {
// (...)
};

New code:

<?php
// (...)
$app->extend('translator', function($translator, $app) {
// (...)
};

On top of that, TranslationServiceProvider() apparently needs an instance of LocaleServiceProvider(). Add this line of code where you declare your Service Providers:

<?php
$app->register(new Silex\Provider\LocaleServiceProvider());

URL Generator

UrlGeneratorServiceProvider() has moved to the core and does not have to be registered separately anymore.

Meaning you can remove this line of code where you declare your Service Providers:

<?php
$app->register(new Silex\Provider\UrlGeneratorServiceProvider());

Request stack

The way requests are handled in the application has changed and now uses the Request Stack. In practice, this means there’s a different syntax for getting information about the current request.

Current request

Old code:

<?php
$app['request']->getRequestUri();

New code:

<?php
$app['request_stack']->getCurrentRequest()->getRequestUri()

This also means that for example:

<?php
$app['request']->getBaseUrl()

becomes

<?php
$app['request_stack']->getCurrentRequest()->getBaseUrl()
Master request

Old code:

<?php
$request->get("_route");

New code:

<?php
$app['request_stack']->getMasterRequest()->attributes->get('_route');

Forms

Comparing the old documentation and the new documentation I found that forms are declared differently now.

Old code:

<?php
$form = $app['form.factory']->createBuilder('form',$data)
  ->add('name','text', array(
    // (...)
  ));

New code:

<?php

use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;

$form = $app['form.factory']->createBuilder(FormType::class,$data)
  ->add('name',TextType::class,array(
    // (...)
  ));

Please note that you have to use the FormType class for the createBuilder method and for each field type, you should use separate components. Check the documentation for all the available field types.

That’s all!

This is all I had to change to upgrade Silex 1.x to 2.x. I hope this is a nice supplement to the official documentation that speeds up the upgrading process.


Sources