Silex2.0


## はじめに
最近、Silex2.0で小さめのWebアプリを作る機会があり、[BC Break]（後方互換性を壊す変更）がそれなりにあるなーという印象でしたので、ここに、まとめておきます。

## Silex (1.2.4 => 2.0.2)変更点まとめ
Changelogは[こちら](http://silex.sensiolabs.org/doc/master/changelog.html)を参照。

### 1.3.0 (2015-06-05)
- PHP5.3.9以上
- Symfony2.7, 2.8のサポート（2.3, 2.5, および 2.6 との互換性は維持）
  - [PR #1097](https://github.com/silexphp/Silex/pull/1097)で詳細がわかる
  - `$app['validator']`が`Validator`クラス（非推奨）から`RecursiveValidator`クラスに変更
  - `$app['form.csrf_provider']`が`Symfony\Component\Form\Extension\Csrf\CsrfProvider\DefaultCsrfProvider`から
  `Symfony\Component\Security\Csrf\CsrfTokenManager`に変更
- `TwigCoreExtension`クラスが削除、`HttpFragmentServiceProvider`の登録が必要に
- `$app['exception_handler']->disable()`は非推奨。かわりに`unset($app['exception_handler'])`を使用

### 1.3.3 (2015-09-08)
-  Symfony 3.0 および Twig 2.0のサポート

### 2.0.0 (2016-05-18)
- PHP5.5.0以上
- Symfony2.8以上
- Pimple1.1.1 => 3.0.2
- CSRF機能はFormから切り離され、独立したプロバイダ（`CsrfServiceProvider`）に
- ロケールの管理は、`LocaleServiceProvider`に集約
- `ServiceProviderInterface`は、`Pimple\ServiceProviderInterface`に変更
  - `boot`メソッドは削除
  - `register`メソッドの引数`$app`が`Silex\Application`から`Pimple\Container`に変更
- `$app['request']`は削除、替わりに`$app['request_stack']`を使用

## Pimple (1.1.1 => 3.0.2)変更点まとめ
Changelogは[こちら](https://github.com/silexphp/Pimple/blob/master/CHANGELOG)を参照。

### 2.1.0 (2014-06-24)
- `Pimple\ServiceProviderInterface`を追加

### 3.0.0 (2014-07-24)
- Pimpleクラスを廃止、替わりに`Pimple\Container`を使用
  - `share`メソッドが削除。替わりに`callable`を直接代入する。
  
    ```php
    $app['service'] = function () {
        return new Service();
    }
    ```

## Symfony (2.6 => 3.0)変更点まとめ

### UPGRADE FROM 2.6 to 2.7
UPGRADEガイドは[こちら](https://github.com/symfony/symfony/blob/2.8/UPGRADE-2.7.md)

#### Form
- `AbstractType`（または`AbstractExtensionType`）の`setDefaultOptions`が非推奨（deprecated）になり、
かわりに`configureOptions`に変更
- `choices`のラベルと値が逆に。keyとvalueをひっくり返して、かつ、`choices_as_values`を`true`にする必要あり

  ```php
  /** Before */
  $form->add('status', 'choice', array(
        'choices' => array(
             Status::ENABLED => 'Enabled',
             Status::DISABLED => 'Disabled',
             Status::IGNORED => 'Ignored',
        )),
));
  ```
  
  ```php
  /** After */
  $form->add('status', 'choice', array(
        'choices' => array(
            'Enabled' => Status::ENABLED,
            'Disabled' => Status::DISABLED,
            'Ignored' => Status::IGNORED,
        ),
        'choices_as_values' => true,
        // important if you rely on your option value attribute (e.g. for JavaScript)
        // this will keep the same functionality as before
        'choice_value' => function ($choice) {
            return $choice;
        },
  ));
  ```

### UPGRADE FROM 2.7 to 2.8
UPGRADEガイドは[こちら](https://github.com/symfony/symfony/blob/2.8/UPGRADE-2.8.md)

#### Form
- `csrf_provider`オプションが非推奨に。かわりに`csrf_token_manager`を使用
- `FormType`を名前で指定するのが非推奨に。かわりにフル修飾クラス名（FQCN）を使用

  ```php
  /** Before */
  $form = $this->createFormBuilder()
      ->add('name', 'text')
      ->add('age', 'integer')
      ->getForm();
  ```

  ```php
  /** After */
  use Symfony\Component\Form\Extension\Core\Type\IntegerType;
  use Symfony\Component\Form\Extension\Core\Type\TextType;
  
  $form = $this->createFormBuilder()
      ->add('name', TextType::class)
      ->add('age', IntegerType::class)
      ->getForm();
  ```

- `Form::add()`、`FormBuilder::add()` および `FormFactory::create*()` で、typeのインスタンスを渡すのは非推奨に。
かわりにフル修飾クラス名（FQCN）を使用

### UPGRADE FROM 2.x to 3.0
UPGRADEガイドは[こちら](https://github.com/symfony/symfony/blob/2.8/UPGRADE-3.0.md)
以下、主に2.8からの差分について記載します。

#### Form
2.8までに非推奨だったものが軒並み削除されています。

- `cascade_validation`オプションは削除
- `FormType`の名前での指定が廃止。かわりにフル修飾クラス名（FQCN）を使用
- `FormTypeInterface::getName()`が削除
- `setDefaultOptions`が削除。かわりに`configureOptions`を使用
- `Form::bind()` および `Form::isBound()`が削除。
かわりに`Form::submit()` および `Form::isSubmitted()`を使用
- `Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface`が削除。
かわりに`Symfony\Component\Security\Csrf\CsrfTokenManagerInterface`を使用
- `csrf_provider` および `intention`が削除。
かわりに`csrf_token_generator` および `csrf_token_id`を使用
- `Form::getErrorsAsString()` が削除。 
かわりに、`Form::getErrors(true, false)`（$deep = true, $flatten = false）を使用
- `choices_as_values`が削除。`choices`は ラベル => 値 の形式で指定

#### Validator
- `ValidatorInterface`が`Validator\ValidatorInterface`に移動
- `validateValue`関数が削除。かわりに`validate`関数を使用

  ```php
  /** Before */
  $validator->validate($object, 'Strict');
  
  $validator->validateValue($value, new NotNull());
  ```
  
  ```php
  /** After */
  $validator->validate($object, null, 'Strict');
  
  $validator->validate($value, new NotNull());
  ```

## おわりに
Silex2.0についての所感をざっと、過剰書きにします。

- 大きなパフォーマンス改善や機能追加は見当たらない
- Silex自体はmicro frameworkなので、利用しているコンポーネントの変更に影響を受ける
- 正直、Symfony2.8、3.0に対応しただけという印象
- Formコンポーネント、ユーザーにメリットない変更多すぎ

とはいえ、Silex1.2は、Symfony2.6までしかサポートしません。
Symfony2.6は、2016/01にサポート切れてしまっていますので、何らかマイグレーション考えましょう。

- [updated deps as Silex 1.2 is not compatible with Symfony 2.7](https://github.com/silexphp/Silex/pull/1098)
- [The Release Process (Contributing to Symfony)](http://symfony.com/doc/current/contributing/community/releases.html)

個人的には、Silex1.2から2.0だったら、Symfonyに限らず他のフレームワークへのマイグレーションを検討してもいいのではと考えています。