Help us understand the problem. What is going on with this article?

Symfony 2.7 から 2.8 への移行

More than 5 years have passed since last update.

Symfony 2.7 から 2.8 への移行

Form

  • "cascade_validation" オプションが非推奨となりました。代わりに "constraints" オプションで Valid バリデーション制約を指定して下さい。 "constraints" オプションは "cascade_validation" と異なり、親フォームではなく各子フォームに設定する必要があります。

変更前:

$form = $this->createFormBuilder($article, array('cascade_validation' => true))
   ->add('author', new AuthorType())
   ->getForm();

変更後:

use Symfony\Component\Validator\Constraints\Valid;

$form = $this->createFormBuilder($article)
   ->add('author', new AuthorType(), array(
       'constraints' => new Valid(),
   ))
   ->getForm();

Valid バリデーション制約はモデル自身に設定しても構いません:

use Symfony\Component\Validator\Constraints as Assert;

class Article
{
   /**
    * @Assert\Valid
    */
   private $author;
}
  • タイプ名は非推奨となり、3.0で削除されます。今後はタイプの参照にはタイプ名ではなく、タイプの完全修飾クラス名(FQCN)を使用する必要があります。PHP 5.5以降では "class" 定数を使用すると良いでしょう:

変更前:

$form = $this->createFormBuilder()
   ->add('name', 'text')
   ->add('age', 'integer')
   ->getForm();

変更後:

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();

それに伴って FormTypeInterface::getName() メソッドも非推奨となり、3.0で削除される為、フォームタイプからこのメソッドを削除する必要があります。

Twigで独自のblock prefixを使用する場合、今後は FormTypeInterface::getBlockPrefix() を実装して下さい:

変更前:

class UserProfileType extends AbstractType
{
   public function getName()
   {
       return 'profile';
   }
}

変更後:

class UserProfileType extends AbstractType
{
   public function getBlockPrefix()
   {
       return 'profile';
   }
}

AbstractTypeの getBlockPrefix() メソッドをオーバーライドしない場合、block prefixにはクラス名から末尾の "Type" を除き、スネークケース化された文字列が使用されます(上記の場合は "user_profile" です)。

もしSymfony 2.3〜2.8間で互換性のあるフォームタイプを作りたい場合は、DEPRECATIONエラーを発生させない為に getName()getBlockPrefix()両方を実装する必要があります:

class ProfileType extends AbstractType
{
   public function getName()
   {
       return $this->getBlockPrefix();
   }

   public function getBlockPrefix()
   {
       return 'profile';
   }
}

更に、フォームタイプをDependency Injectionに登録している場合は、"alias" 引数を削除する必要があります:

変更前:

<service id="my.type" class="Vendor\Type\MyType">
   <tag name="form.type" alias="mytype" />
</service>

変更後:

<service id="my.type" class="Vendor\Type\MyType">
   <tag name="form.type" />
</service>

タイプエクステンションは、今後拡張するフォームタイプの完全修飾クラス名を返す必要があります。

変更前:

class MyTypeExtension extends AbstractTypeExtension
{
   public function getExtendedType()
   {
       return 'form';
   }
}

変更後:

use Symfony\Component\Form\Extension\Core\Type\FormType;

class MyTypeExtension extends AbstractTypeExtension
{
   public function getExtendedType()
   {
       return FormType::class;
   }
}

タイプ同様、Symfony 2.3〜2.8に互換性のあるタイプエクステンションを作る場合は getExtendedType() メソッドを次のように実装して下さい:

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\FormType;

class MyTypeExtension extends AbstractTypeExtension
{
   public function getExtendedType()
   {
       return method_exists(AbstractType::class, 'getBlockPrefix') ? FormType::class : 'form';
   }
}
  • FormTypeInterface::getParent() で親のタイプインスタンスを返す事は、2.8で非推奨となり、3.0ではサポートされなくなります。 今後は親のフォームタイプの完全修飾クラス名を返すようにしましょう。

変更前:

class MyType
{
   public function getParent()
   {
       return new ParentType();
   }
}

変更後:

class MyType
{
   public function getParent()
   {
       return ParentType::class;
   }
}
  • Form::add()FormBuilder::add()FormFactory::create*() メソッドも同様に、タイプインスタンスを渡す事は3.0以降できなくなります。 他の変更と同様、完全修飾クラス名を渡すようにして下さい。

変更前:

$form = $this->createForm(new MyType());

変更後:

$form = $this->createForm(MyType::class);
  • タイプエクステンションをサービスとして登録する際、getExtendedType() メソッドの返り値と異なるタイプのaliasを使う事ができなくなった為、正しいタイプに修正する必要があります。

  • form.type_extension タグのaliasは非推奨となりました。代わりに extended_type または extended-type を使いましょう。

変更前:

<service id="app.type_extension" class="Vendor\Form\Extension\MyTypeExtension">
   <tag name="form.type_extension" alias="text" />
</service>

変更後:

<service id="app.type_extension" class="Vendor\Form\Extension\MyTypeExtension">
   <tag name="form.type_extension" extended-type="Symfony\Component\Form\Extension\Core\Type\TextType" />
</service>

Translator

  • Symfony\Component\Translation\TranslatorgetMessages() メソッドは非推奨となり、Symfony 3.0で削除されます。 代わりに Symfony\Component\Translation\TranslatorBagInterfacegetCatalogue() メソッドを使いましょう。

変更前:

$messages = $translator->getMessages();

変更後:

$catalogue = $translator->getCatalogue($locale);
$messages = $catalogue->all();

while ($catalogue = $catalogue->getFallbackCatalogue()) {
    $messages = array_replace_recursive($catalogue->all(), $messages);
}

DependencyInjection

  • scopeの概念は非推奨となりました。この為、次のメソッドが非推奨になりました:

    • Symfony\Component\DependencyInjection\ContainerBuilder::getScopes()
    • Symfony\Component\DependencyInjection\ContainerBuilder::getScopeChildren()
    • Symfony\Component\DependencyInjection\ContainerInterface::enterScope()
    • Symfony\Component\DependencyInjection\ContainerInterface::leaveScope()
    • Symfony\Component\DependencyInjection\ContainerInterface::addScope()
    • Symfony\Component\DependencyInjection\ContainerInterface::hasScope()
    • Symfony\Component\DependencyInjection\ContainerInterface::isScopeActive()
    • Symfony\Component\DependencyInjection\Definition::setScope()
    • Symfony\Component\DependencyInjection\Definition::getScope()
    • Symfony\Component\DependencyInjection\Reference::isStrict()

これに加え、Symfony\Component\DependencyInjection\ContainerInterface::set()$scope と、 Symfony\Component\DependencyInjection\Reference$strict パラメーターがそれぞれ非推奨となりました。

  • prototype スコープの代替として、サービス定義に shared と言う新しいフラグが追加されました。

変更前:

use Symfony\Component\DependencyInjection\ContainerBuilder;

$container = new ContainerBuilder();
$container
   ->register('foo', 'stdClass')
   ->setScope(ContainerBuilder::SCOPE_PROTOTYPE)
;
services:
   foo:
       class: stdClass
       scope: prototype
<services>
   <service id="foo" class="stdClass" scope="prototype" />
</services>

変更後:

use Symfony\Component\DependencyInjection\ContainerBuilder;

$container = new ContainerBuilder();
$container
   ->register('foo', 'stdClass')
   ->setShared(false)
;
services:
   foo:
       class: stdClass
       shared: false
<services>
   <service id="foo" class="stdClass" shared="false" />
</services>

WebProfiler

  • profiler:import および profiler:export コマンドは非推奨となり、Symfony 3.0で削除されます。

  • Webデバッグツールバーのデザインが刷新されました。これにあわせ、ツールバーのHTMLマークアップが多少変更されました。

変更前:

情報は単なる <span> タグで囲まれていただけでした:

{% block toolbar %}
   {% set icon %}
       <span>
           <svg ...></svg>
           <span>{{ '%.1f'|format(collector.memory / 1024 / 1024) }} MB</span>
       </span>
   {% endset %}
{% endblock %}

変更後:

今後は値とラベル毎にそれぞれ異なる class を持つ <span> にラップされます:

{% block toolbar %}
   {% set icon %}
       <svg ...></svg>
       <span class="sf-toolbar-value">
           {{ '%.1f'|format(collector.memory / 1024 / 1024) }}
       </span>
       <span class="sf-toolbar-label">MB</span>
   {% endset %}
{% endblock %}

以前のデザインで使用されていたblockの殆どが利用可能ですが、新旧両方のデザインに対応したツールバーを作成する場合は、テンプレートに渡される新しい変数 profiler_markup_version を利用すると良いでしょう:

{% block toolbar %}
   {% set profiler_markup_version = profiler_markup_version|default(1) %}

   {% set icon %}
       {% if profiler_markup_version == 1 %}

           {# code for the original toolbar #}

       {% else %}

           {# code for the new toolbar (Symfony 2.8+) #}

       {% endif %}
   {% endset %}
{% endblock %}
  • FileProfilerStorage 以外の全てのプロファイラーストレージは非推奨となりました。具体的には以下のクラスが該当します:

    • Symfony\Component\HttpKernel\Profiler\BaseMemcacheProfilerStorage
    • Symfony\Component\HttpKernel\Profiler\MemcachedProfilerStorage
    • Symfony\Component\HttpKernel\Profiler\MemcacheProfilerStorage
    • Symfony\Component\HttpKernel\Profiler\MongoDbProfilerStorage
    • Symfony\Component\HttpKernel\Profiler\MysqlProfilerStorage
    • Symfony\Component\HttpKernel\Profiler\PdoProfilerStorage
    • Symfony\Component\HttpKernel\Profiler\RedisProfilerStorage
    • Symfony\Component\HttpKernel\Profiler\SqliteProfilerStorage

今後は FileProfileStorage あるいは、ProfileStorageInterface を実装した独自のストレージを使いましょう。

FrameworkBundle

  • session.cookie_httponly パラメーターのデフォルト値が true になりました。 これはJavaScriptのようなスクリプト言語からのCookieへのアクセスを防ぎ、XSS攻撃によってIDを盗まれる危険性を減らせます。 引き続きセッションのCookieにアクセスする場合はこのパラメーターをオーバーライドして下さい:
framework:
   session:
       cookie_httponly: false

Security

  • AbstractToken::isGranted() メソッドは非推奨となりました。代わりに voteOnAttribute() をオーバーライドして下さい。 このメソッドにはユーザーの代わりにTokenInterfaceが渡されます:

変更前:

class MyCustomVoter extends AbstractVoter
{
   // ...

   protected function isGranted($attribute, $object, $user = null)
   {
       // ...
   }
}

変更後:

class MyCustomVoter extends AbstractVoter
{
   // ...

   protected function voteOnAttribute($attribute, $object, TokenInterface $token)
   {
       $user = $token->getUser();
       // ...
   }
}

Config

  • \Symfony\Component\Config\Resource\ResourceInterface::isFresh() メソッドは非推奨となり、Symfony 3.0で削除されます。 全てのリソースの実装が必ずしも鮮度の確認を自分自身で行えるとは限らない為です。

このメソッドを実装しているリソースは、\Symfony\Component\Config\Resource\ResourceInterface の代わりに、これを継承する \Symfony\Component\Config\Resource\SelfCheckingResourceInterface を実装して下さい。

変更前:

use Symfony\Component\Config\Resource\ResourceInterface;

class MyCustomResource implements ResourceInterface { ... }

変更後:

use Symfony\Component\Config\Resource\SelfCheckingResourceInterface;

class MyCustomResource implements SelfCheckingResourceInterface { ... }

また、新しく追加された ResourceChecker ベースのキャッシュ検証システムの導入も検討してみて下さい。


Source: https://raw.githubusercontent.com/symfony/symfony/86b4c0536cac411cdbe7cef3c1c68f17c49d49ec/UPGRADE-2.8.md

issei-m
Symfony, Doctrineが好きなぺちぱー
http://issei-m.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away