Home | Symfony2Doc

コンテンツ上部に更新日の記載のないページは、翻訳の内容が2.0相当のものになっております。最新の内容は原文のページをご確認ください。

Note

  • 対象バージョン:2.3以降
  • 翻訳更新日:2014/04/30

後方互換性の保証について

私達はプロジェクトの円滑なアップグレードの保証を最重視している為、Symfonyではすべてのマイナーリリース間の後方互換性を保証します。 このようなバージョン管理の方式をセマンティックバージョニングと呼びます。 セマンティックバージョニングは、互換性のないAPIの変更はメジャーリリース(2.0や3.0など)でのみ行い、マイナーリリース(2.5や2.6のような)では新機能の追加は、そのリリースブランチ(前の例で言う2.x)の既存のAPIの後方互換性が保たれた状態で行われます。

Caution

この保証はSymfony 2.3 から施行されたため、その前のバージョンには適用されません。

しかし、後方互換性の破壊はあらゆる場面で起きます。 実際には、フレームワークに行われるほぼすべての変更がアプリケーションを破壊する可能性があると言っても過言ではありません。 例えば、Symfonyのクラスをアプリケーションで継承して使っている場合、あなたが既に追加したメソッドとシグネチャの異なる同名のメソッドが追加された時にアプリケーションが壊れてしまいます。

同時に、全ての後方互換性の破壊がアプリケーションに影響を与えると言うわけではありません。 既存のクラスやアーキテクチャに大幅な変更が必要な場合がある一方で、単にメソッド名を変更する等、簡単に解決できる場合もあります。

そこで私達はこのページを作りました。”Symfonyコードの利用”セクションでは、どのようにすればアプリケーションを壊す事なく、新しいマイナーバージョンに確実にアップグレードできるかについて説明します。

次の”Symfonyコードへの取り組み”は、Symfonyのコントリビュータ向けのセクションです。 このセクションではユーザが円滑にアップグレードを行えるように、すべてのコントリビュータが守るべき規則の詳細を列挙します。

Symfonyコードの利用

以下のガイドラインに沿ってSymfonyを使用していれば、今後のすべてのマイナーバージョンに円滑にアップグレードする事ができます。

インターフェースの利用

Symfonyが用意する全てのインターフェースはタイプヒントで指定する事ができ、宣言されている全てのメソッドをコールすることができます。 これらの規則に従うコードは壊される事はありません。

Caution

@internalタグが付いているインターフェースは保証外になります。このようなインターフェースは使用、または実装すべきでありません。

インターフェースを実装する場合は、まずそれがAPIインターフェースであるか確認しましょう。次のような、@apiタグの付いている物はAPIインターフェースとなります:

/**
 * HttpKernelInterface handles a Request to convert it to a Response.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @api
 */
interface HttpKernelInterface
{
    // ...
}

APIインターフェースを実装していれば、将来そのコードが壊される事はありません。対照的に、レギュラーインターフェースはマイナーリリース時に新しいメソッドを追加する等の拡張がされる事がある為、アップグレードの際は事前に確認を行い、必要に応じて手動でコードを移行する必要があります。

Note

容易に移行が可能な変更だけが行われます。また、それらの変更がある際はSymfonyルートディレクトリに配置されるUPGRADEファイルに正確な移行の指示を明記します。

次の表は、どのようなユースケースで後方互換性が保たれるかを説明します。

ユースケース レギュラー API
あなたが... する場合は後方互換性を保証...
インターフェースへのタイプヒント Yes Yes
メソッドをコール Yes Yes
あなたがインターフェースを実装し、かつ、... する場合は後方互換性を保証...
メソッドを実装 No [1] Yes
実装したメソッドに引数を追加 No [1] Yes
引数にデフォルト値を設定 Yes Yes

クラスの利用

Symfonyによって提供されるすべてのクラスはインスタンス化され、publicメソッドおよびプロパティを介してアクセスする事ができます。

Caution

@internalタグの付いたクラス、プロパティやメソッド、並びに名前空間に**Tests**を含むクラスはこの規約の対象外となります。 これらは内部利用を目的としているので、アプリケーションのコードからアクセスすべきではありません。

インターフェースと同様、クラスもAPIクラス、レギュラークラスと区分されています。 APIクラスもインターフェースと同様に@apiタグが付けられています:

/**
 * Request represents an HTTP request.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @api
 */
class Request
{
    // ...
}

APIクラスとレギュラークラスの違いは、APIクラスは継承先でオーバーライドしたメソッドは完全に後方互換性が保証されるのに対し、レギュラークラスはその限りではないと言う点です。 例えば省略可能な引数がメソッドに追加される事があります。その結果、あなたがオーバーライドしたメソッドとのシグネチャに不一致が生じた場合、致命的なエラーが発生するでしょう。

Note

インターフェースと同様に、クラスの変更は最小限に留められ、移行が必要な場合はSymfonyルートディレクトリに配置されるUPGRADEにその詳細な手順を示します。

場合によっては、@apiタグがクラス単位ではなく、特定のプロパティやメソッドにのみ付けられている事があります。 このような場合、そのプロパティやメソッドに対する(下図のAPI列で示すように)後方互換性は保証されますが、それ以外の部分に関してはその限りではないと言う事を意味します。

念のため、以下のユースケースと後方互換性保証の対応表を確認して下さい:

ユースケース レギュラー API
あなたが... する場合は後方互換性を保証...
クラスへのタイプヒント Yes Yes
新しいインスタンスを作成 Yes Yes
クラスを継承 Yes Yes
publicプロパティにアクセス Yes Yes
publicメソッドをコール Yes Yes
あなたがクラスを継承し、かつ、... する場合は後方互換性を保証...
protectedプロパティにアクセス No [1] Yes
protectedメソッドをコール No [1] Yes
publicプロパティをオーバーライド Yes Yes
protectedプロパティをオーバーライド No [1] Yes
publicメソッドをオーバーライド No [1] Yes
protectedメソッドをオーバーライド No [1] Yes
新しいプロパティを追加 No No
新しいメソッドを追加 No No
オーバーライドしたメソッドに引数を追加 No [1] Yes
引数にデフォルト値を追加 Yes Yes
(Reflectionから)privateメソッドのコール No No
(Reflectionから) privateプロパティにアクセス No No

Symfony Codeへの取り組み

Symfonyの改善に貢献する場合、ユーザーの円滑なアップグレードを保証する為に下記で示すルールに厳格に則る必要があります。

インターフェースへの変更

次の表では、既存インターフェースに対して許可されている変更を示します:

変更の内容 レギュラー API
インターフェースそのものを削除 No No
インターフェース名、あるいは名前空間の変更 No No
親インターフェースの追加 Yes [2] Yes [3]
親インターフェースの削除 No No
メソッド    
メソッドの追加 Yes [2] No
メソッドの削除 No No
メソッド名の変更 No No
親インターフェースに移動 Yes Yes
デフォルト値を持たない引数の追加 No No
デフォルト値を持つ引数の追加 Yes [2] No
引数の削除 Yes [4] Yes [4]
引数にデフォルト値を設定 Yes [2] No
引数のデフォルト値を削除 No No
引数にタイプヒントを設定 No No
引数のタイプヒントを削除 Yes [2] No
引数の型を変更 Yes [2] [5] No
戻り値の型を変更 Yes [2] [6] No

クラスへの変更

次の表では、既存クラスに対して許可されている変更を示します:

変更の内容 レギュラー API
クラスそのものを削除 No No
finalに変更 No No
abstractに変更 No No
クラス名、あるいは名前空間の変更 No No
親クラスの変更 Yes [7] Yes [7]
インターフェースの追加 Yes Yes
インターフェースの削除 No No
publicプロパティ    
publicプロパティの追加 Yes Yes
publicプロパティの削除 No No
スコープの降格 No No
親クラスに移動 Yes Yes
protectedプロパティ    
protectedプロパティの追加 Yes Yes
protectedプロパティの削除 Yes [2] No
スコープの降格 Yes [2] No
親クラスに移動 Yes Yes
privateプロパティ    
privateプロパティの追加 Yes Yes
privateプロパティの削除 Yes Yes
コンストラクタ    
必須な引数のないコンストラクタの追加 Yes [2] Yes [2]
コンストラクタの削除 Yes [2] No
publicコンストラクタのスコープの降格 No No
protectedコンストラクタのスコープの降格 Yes [2] No
親クラスに移動 Yes Yes
publicメソッド    
publicメソッドの追加 Yes Yes
publicメソッドの削除 No No
メソッド名の変更 No No
スコープの降格 No No
親クラスに移動 Yes Yes
デフォルト値を持たない引数の追加 No No
デフォルト値を持つ引数の追加 Yes [2] No
引数の削除 Yes [4] Yes [4]
引数にデフォルト値を設定 Yes [2] No
引数のデフォルト値を削除 No No
引数にタイプヒントを設定 Yes [8] No
引数のタイプヒントを削除 Yes [2] No
引数の型を変更 Yes [2] [5] No
戻り値の型を変更 Yes [2] [6] No
protectedメソッド    
protectedメソッドの追加 Yes Yes
protectedメソッドの削除 Yes [2] No
メソッド名の変更 No No
スコープの降格 Yes [2] No
親クラスに移動 Yes Yes
デフォルト値を持たない引数の追加 Yes [2] No
デフォルト値を持つ引数の追加 Yes [2] No
引数の削除 Yes [4] Yes [4]
引数にデフォルト値を設定 Yes [2] No
引数のデフォルト値を削除 Yes [2] No
引数にタイプヒントを設定 Yes [2] No
引数のタイプヒントを削除 Yes [2] No
引数の型を変更 Yes [2] [5] No
戻り値の型を変更 Yes [2] [6] No
privateメソッド    
protectedメソッドの追加 Yes Yes
protectedメソッドの削除 Yes Yes
メソッド名の変更 Yes Yes
スコープの降格 Yes Yes
デフォルト値を持たない引数の追加 Yes Yes
デフォルト値を持つ引数の追加 Yes Yes
引数の削除 Yes Yes
引数にデフォルト値を設定 Yes Yes
引数のデフォルト値を削除 Yes Yes
引数にタイプヒントを設定 Yes Yes
引数のタイプヒントを削除 Yes Yes
引数の型を変更 Yes Yes
戻り値の型を変更 Yes Yes
[1](1, 2, 3, 4, 5, 6, 7, 8) アプリケーションのコードはSymfonyのアップグレード時に破損する可能性があるが、 その際はUPGRADEファイルに移行の手順が明記される。
[2](1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28) 基本的に行うべきではない。行う場合はUPGARADEファイルに変更を明記する必要がある。
[3]追加される親インターフェースは、現状のインターフェースに存在しない新しいメソッドを定義してはならない。
[4](1, 2, 3, 4, 5, 6) 最後の引数(複数可)のみ削除可能。PHPは余分な引数の受け渡しを無視する為。
[5](1, 2, 3)

引数の型は互換性がある、またはより曖昧な型にのみ変更可能。許可されている変更は次の通り:

変更元の型 変更先の型
boolean boolean値と等価に評価可能なスカラー型
string string値と等価に評価可能なスカラー型またはオブジェクト
integer integer値と等価に評価可能なスカラー型
float float値と等価に評価可能なスカラー型
class <C> <C> のスーパークラス、またはこれが実装しているいずれかのインターフェース
interface <I> <I> のスーパーインタフェース
[6](1, 2, 3)

戻り値の型は互換性がある、またはより具体的な型にのみ変更可能。許可されている変更は次の通り:

変更元の型 変更先の型
boolean boolean値と等価に評価可能なスカラー型
string string値と等価に評価可能なスカラー型またはオブジェクト
integer integer値と等価に評価可能なスカラー型
float float値と等価に評価可能なスカラー型
array ArrayAccessTraversableおよびCountableを実装しているインスタンス
ArrayAccess array
Traversable array
Countable array
class <C> <C> のサブクラス
interface <I> <I> のサブインターフェース、またはこれを実装しているクラス
[7](1, 2) 変更される親クラスは、元のクラスの先祖である必要がある。
[8]異なる型の値を渡した際にFatalエラーが発生する場合にのみタイプヒントを設定できる。
blog comments powered by Disqus