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\Translator
のgetMessages()
メソッドは非推奨となり、Symfony 3.0で削除されます。
代わりにSymfony\Component\Translation\TranslatorBagInterface
のgetCatalogue()
メソッドを使いましょう。変更前:
$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
ベースのキャッシュ検証システムの導入も検討してみて下さい。