5.0 移行ガイド
CakePHP 5.0 には、破壊的な変更が含まれており、4.x リリースとの後方互換性はありません。 5.0 にアップグレードする前に、最初に 4.5 にアップグレードし、すべての非推奨警告を解消してください。
5.0 にアップグレードする方法の段階的な手順については、 5.0 アップグレードガイド を参照してください。
非推奨機能の削除
4.5 で非推奨の警告を発していたすべてのメソッド、プロパティと機能が削除されました。
破壊的変更
非推奨機能の削除に加えて、破壊的変更が行われました。
全体
全ての関数について、可能な限り、引数や返り値の型が明示されるようになりました。DockBlockに書かれた注釈(annotation)に合致するように意図しましたが、DockBlock側を修正した箇所もあります。
クラスのpropertyについても同様に型が可能な限り明示されるようになりました。こちらでも注釈を修正した箇所もあります。
次の定数が削除されました :
SECOND,MINUTE,HOUR,DAY,WEEK,MONTH,YEAR全ての
#[\AllowDynamicProperties]指定が削除されました。これは以下のクラスで使用されていました。Command/CommandConsole/ShellController/ComponentController/ControllerMailer/MailerView/CellView/HelperView/View
サポート対象のデータベースエンジンのバージョンが更新されました。
- MySQL (5.7 以上)
- MariaDB (10.1 以上)
- PostgreSQL (9.6 以上)
- Microsoft SQL Server (2012 以上)
- SQLite 3 (3.16 以上)
Auth
- Auth は削除されました。代わりに cakephp/authentication および
cakephp/authorization プラグインを使用してください。
Cache
Wincacheエンジンは削除されました。wincache拡張は PHP 8 ではサポートされていないため、です。
Collection
combine()は、指定した key path や group path が存在しないまたは null 値の場合に、例外を投げるようになりました。 この挙動は、indexBy()やgroupBy()と同じです。
Console
BaseCommand::__construct()は削除されました。ConsoleIntegrationTestTrait::useCommandRunner()は、もはや必要無いため削除されました。Shellは削除されました。代わりに Command をお使い下さい。ConsoleOptionParser::addSubcommand()はShellの削除とともに削除されました。
サブコマンドはCommandクラスで置き換えてください。 必要なコマンド名はCommand::defaultName()を実装することで定義できます。BaseCommandはexecute()メソッドがフレームワークから呼び出される前後にCommand.beforeExecuteおよびCommand.afterExecuteのイベントを発行するようになりました。
Connection
Connection::prepare()は削除されました。これは、SQL文、パラメータ、パラメータ型の情報を渡すことでConnection::execute()の1回の呼び出しに置き換えることができます。Connection::enableQueryLogging()は削除されました。データベース接続設定においてロギングを有効にしていない場合、$connection->getDriver()->setLogger()を呼び出して logger インスタンスを設定することにより、後からロギングを有効にできます。
Controller
Controller::__construct()は削除されました。サブクラスでoverrideしていた場合は、コードの調整をお願いします。- Component は、 Controller の読み込み後に dynamic property として設定されることは無くなりました。代わりに Controller は
__get()を用いて Component へのアクセスを提供します。この変更は、 Component の存在有無をproperty_exists()でチェックしているアプリケーションに影響を与えます。 - Component が発行していた
Controller.shutdownイベントは、shutdownからafterFilterに名称変更されました。Controller に合わせるためです。これにより callback はより首尾一貫したものとなります。 PaginatorComponentは削除されました。代わりに、 Controller で$this->paginate()を呼び出すか、直接Cake\Datasource\Paging\NumericPaginatorを用いて下さい。RequestHandlerComponentは削除されました。アップグレード方法は 4.4 移行ガイド を参照して下さい。SecurityComponentは削除されました。代わりにFormProtectionComponentで耐タンパ性を得たり、HttpsEnforcerMiddlewareを使って HTTPS を強制したりして下さい。Controller::paginate()は、その引数$settingsにおいてcontainオプション等を受け付けなくなりました。代わりにfinderオプションを使って$this->paginate($this->Articles, ['finder' => 'published'])などとして下さい。事前にクエリを組み立てておいてそれをpaginate()に渡すこともできます。例えば$query = $this->Articles->find()->where(['is_published' => true]); $this->paginate($query);となります。
Core
- 関数
getTypeName()は削除されました。代わりに、PHPのget_debug_type()をお使い下さい。 - 依存ライブラリ
league/containerは4.xに更新されました。これによってServiceProviderの実装には追加の型ヒントが必要となります。 deprecationWarning()には引数$versionが追加されました。App.uploadedFilesAsObjectsオプションは、PHPそのもののファイルアップロードにおける array 生成に倣い、削除されました。ClassLoaderは削除されました。代わりに Composer の autoload の仕組みをお使い下さい。
Database
DateTimeTypeおよびDateTypeは、常に変更不可能(immutable)なオブジェクトを返すようになりました。また、Dateオブジェクトの interface はChronosDateの interface を反映するようになり、CakePHP 4.x で存在した時刻関連のメソッドが無くなりました。DateType::setLocaleFormat()は array を受け付けないようになりました。Queryはcallableではなく\Closureなパラメータのみを受け付けるようになりました。 callable なオブジェクトは PHP 8.1 で導入された、第一級 callable の記法で書き換え可能です。(訳注 : PHPのマニュアル 「第一級callableを生成する記法」 )Query::execute()は、結果を整形するコールバックを呼ばないようになりました。代わりにQuery::all()をお使い下さい。TableSchemaAwareInterfaceは削除されました。Driver::quote()は削除されました。代わりに prepared statement をお使い下さい。Query::orderBy()はQuery::order()の代わりに追加されました。Query::groupBy()はQuery::group()の代わりに追加されました。SqlDialectTraitは削除されました。ここで提供されていた全ての機能はDriverクラスそのものに実装されました。CaseExpressionは削除されました。代わりにQueryExpression::case()またはCaseStatementExpressionをお使い下さい。Connection::connect()は削除されました。代わりに$connection->getDriver()->connect()をお使い下さい。Connection::disconnect()は削除されました。代わりに$connection->getDriver()->disconnect()をお使い下さい。- クエリのログの scope として
queriesLogだけではなくcake.database.queriesも使えるようになりました。 - 結果セットのバッファリングを有効化・無効化する機能は削除されました。常にバッファリングされます。
Datasource
getAccessible()メソッドがEntityInterfaceに追加されました。ORM外でこの interface を実装している場合は、このメソッドも実装する必要があります。aliasField()メソッドがRepositoryInterfaceに追加されました。ORM外でこの interface を実装している場合は、このメソッドも実装する必要があります。
Event
- Event に載せるデータ(payload) は、配列である必要があります。配列ではないオブジェクト、例えば
ArrayAccessは array へのキャストで失敗してTypeErrorを出すようになります。 - イベントハンドラは void メソッドとして実装し、結果は返り値として返却するのではなく
$event->setResult()に渡す方法が推奨されます。
Error
ErrorHandlerおよびConsoleErrorHandlerは削除されました。対応方法は 4.4 移行ガイド をご覧下さい。ExceptionRendererは削除されました。代わりにWebExceptionRendererをお使い下さい。ErrorLoggerInterface::log()は削除されました。代わりにErrorLoggerInterface::logException()をお使い下さい。ErrorLoggerInterface::logMessage()は削除されました。代わりにErrorLoggerInterface::logError()をお使い下さい。
Filesystem
- Filesystem というパッケージは削除されました。
Filesystemというクラスは Utility のパッケージに移動されました。
Http
ServerRequestのfilesは、 array とは互換性は無くなりました。この挙動は 4.1.0 でデフォルトでは停止されていました。このfilesは常にUploadedFileInterfacesオブジェクトを持つようになります。
I18n
FrozenDateは Date に名称変更され、またFrozenTimeも DateTime に名称変更されました。TimeはCake\Chronos\ChronosTimeを継承するようになりました。その結果として変更不可能(immutable)になりました。DateオブジェクトはDateTimeInterfaceを継承しなくなりました。そのため、DateTimeオブジェクトと比較することはできません。
詳細は cakephp/chronos のリリースドキュメント を参照してください。Date::parseDateTime()は削除されました。Date::parseTime()は削除されました。Date::setToStringFormat()およびDate::setJsonEncodeFormat()は、配列を受け付けないようになりました。Date::i18nFormat()およびDate::nice()は、タイムゾーンの引数を受け付けないようになりました。ベンダ名が接頭辞に付いたプラグイン(例えば
FooBar/Awesome)への翻訳ファイルは、接頭辞を含むファイル名として下さい(例えばfoo_bar_awesome.po)。これは、同名の接頭辞無しのプラグイン(例えばAwesome)の翻訳ファイル(この例ではawesome.po)との衝突を避けるためのものです。
Log
- Logエンジンの設定において、特定のスコープを無効化する際には
falseではなくてnullを用いるようになりました。設定ファイルにおいて'scopes' => falseとなっている箇所は'scopes' => nullと書き換えて下さい。
Mailer
Emailは削除されました。代わりに Mailer をお使い下さい。- ログのスコープとして
emailの代わりにcake.mailerも指定できるようになりました。
ORM
EntityTrait::has()は、属性が存在してその値がnullである場合、trueを返すようになりました。過去のCakePHPのバージョンにおいてはfalseを返していました。4.x の挙動が必要な場合の対応方法は、4.5.0 のリリースノートを参照して下さい。(訳注 : 4.5のリリースノートは日本語には翻訳されていません。 英語版の 4.5 の Migration Guide の中ではEntityTrait::hasValue()を使うように案内されています。)EntityTrait::extractOriginal()はextractOriginalChanged()と同様に、存在するフィールドのみを返すようになりました。- Finder の引数は連想配列である必要があります。過去にはこれは推奨事項という位置付けでした。
TranslateBehaviorはデフォルトではShadowTableストラテジを採用するようになりました。もしもEavストラテジを利用中で、その挙動を維持する必要があるのならば、設定を変更する必要があります。isUniqueルールのallowMultipleNullsオプションは、デフォルトではtrueとなり、本来の 3.x の挙動に合致するようになりました。Table::query()は、後述のクエリタイプごとのメソッドが提供されたことに伴い、削除されました。(訳注 : 5.0.5 時点においては実際には削除されておらず、Table::query()はTable::selectQuery()を呼び出しているようです。)Table::updateQuery(),Table::selectQuery(),Table::insertQuery(),Table::deleteQuery()の4つのメソッドが追加されました。これらは以下に示すクエリタイプごとのオブジェクトを返します。SelectQuery,InsertQuery,UpdateQuery,DeleteQueryの4つの型が追加されました。クエリのタイプが型として指定されることで、クエリタイプが変更されたり、無関係な別のクエリタイプの関数を呼んだりするのを防ぐようになりました。Table::_initializeSchema()は削除されました。代わりにinitialize()の中で$this->getSchema()を呼んで下さい。SaveOptionsBuilderは削除されました。通常の配列をお使い下さい。
Routing
Routerのstaticメソッドのconnect(),prefix(),scope(),plugin()は削除されました。代わりにRouteBuilderのインスタンスのメソッドをお使い下さい。RedirectExceptionは削除されました。代わりに\Cake\Http\Exception\RedirectExceptionをお使い下さい。
TestSuite
TestSuiteは削除されました。単体テストの設定をカスタマイズするには、環境変数を使って下さい。TestListenerTraitは削除されました。PHPUnitがこれらの listener のサポートを打ち切ったためです。詳細は PHPUnit 10 へのアップグレード を参照して下さい。IntegrationTestTrait::configRequest()が複数回呼ばれた際、設定を上書きするのではなく merge するようになりました。
Validation
Validation::isEmpty()は、ファイルアップロードの配列には対応しないようになりました。PHPのファイルアップロードの配列への対応はServerRequestからも削除されていますので、この問題はテストの外側の問題だとは捉えないようにして下さい。- 以前は、ほとんどの validation エラーの文言は
The provided value is invalidという単純なものでした。今では例えばThe provided value must be greater than or equal to \`5\のように、もう少し詳細に言及するようになりました。
View
ViewBuilderのオプションは、本当の意味で連想配列となりました(stringのキーを用います)。NumberHelperおよびTextHelperはengine設定を受け付けないようになりました。ViewBuilder::setHelpers()のパラメータ$mergeは削除されました。代わりにViewBuilder::addHelpers()をお使い下さい。View::initialize()の中では、loadHelper()よりもaddHelper()の方が望ましいようになりました。設定されたヘルパーはいずれにせよ後で読み込まれます。View\Widget\FileWidgetは、PHPのファイルアップロードの配列とは互換性が無くなりました。この変更はServerRequestやValidationと同じ趣旨のものです。FormHelperは、CSRF対策トークンのフィールドではautocomplete=offを設定しないようになりました。これはSafariのバグへの応急措置として設定されましたが、今ではもう関係はありません。
非推奨
以下は非推奨となったメソッド、プロパティ、挙動の一覧です。これらの機能は 5.x では動作し続けますが、 6.0 では削除される予定です。
Database
Query::order()は非推奨となりました。代わりにQuery::orderBy()をお使い下さい。この変更はSQL文の機能名称に合わせたものになります。Query::group()は非推奨となりました。代わりにQuery::groupBy()をお使い下さい。この変更はSQL文の機能名称に合わせたものになります。
ORM
Table::find()のオプションを配列で指定することは非推奨となりました。代わりに 名前付き引数 を使用して下さい。例えばfind('all', ['conditions' => $array])の代わりにfind('all', conditions: $array)です。カスタムの finder オプションについても同様にfind('list', ['valueField' => 'name'])の代わりにfind('list', valueField: 'name')を使用して下さい。複数の名前付き引数の場合は例えばfind(type: 'list', valueField: 'name', conditions: $array)となります。
新機能
進化した型チェック
CakePHP 5 は、PHP 8.1 以上で有効な型システムを活用します。 CakePHPは assert() を使うことによっても、詳細なエラーメッセージや、型の安全性を提供します。 本番運用モードにおいては、 assert() でのコード生成を停止させてパフォーマンスを向上させることができます。 この方法については Symlink Assets を参照して下さい。(訳注 : このリンク先は、2024年3月時点ではまだ翻訳されていません。 英語版 で zend.assertions を設定している箇所を参照して下さい。)
Collection
- コールバック関数を用いて重複した値を除去するメソッド
unique()が追加されました。 reject()は、trueっぽい値のみを除外するデフォルトのコールバック関数が利用可能になりました。これはfilter()のデフォルトの挙動の真逆となります。
Core
PluginInterfaceにはservices()メソッドが追加されました。- プラグインの読み込み に
PluginCollection::addFromConfig()が追加されました。
Database
ConnectionManagerは read / write の接続ロールをサポートしました。データベース接続設定においてreadやwriteのキーで指定した設定項目によって共通の設定項目を上書きすることで、接続ロールを構成することができます。- 結果セットを整形するコールバックを実行できるメソッド
Query::all()が追加されました。 - SQLにコメントを追加するメソッド
Query::comment()が追加されました。これによりクエリのデバッグが楽になります。 - PHPの enum と、データベースの string や integer 型との間の橋渡しをする
EnumTypeが追加されました。 DriverInterfaceにgetMaxAliasLength()とgetConnectionRetries()が追加されました。- 以前は integer 型の主キー全てに自動的に auto-increment 指定を入れていましたが、 "id" という名前の integer 型の主キーにのみこの動作をするようになりました。 'autoIncrement' を false に設定することで、この挙動を無効にできます。
Http
- PSR-17 factory interface への対応が追加されました。これによって
cakephp/httpパッケージは、 php-http のように自動で interface resolution を有効にするライブラリに対してclient実装を提供できるようになりました。 - 例外を発することなく便利に cookie を操作できる方法として
CookieCollection::__get()とCookieCollection::__isset()が追加されました。
ORM
必須フィールド
モデルのエンティティには opt-in 方式で利用可能な新しい機能、より厳格なプロパティ操作、が追加されました。 この新しい機能は「必須フィールド」と呼ばれます。 有効化されると、エンティティで定義されていないプロパティにアクセスした場合に例外が発生します。 これは以下のようなコードに影響を与えます:
$entity->get();
$entity->has();
$entity->getOriginal();
isset($entity->attribute);
$entity->attribute;フィールドは array_key_exists が true を返す場合に「定義されている」と判断されます。 これは null 値も含まれます。 この機能はうんざりするようなものであるかもしれないので、5.0 まで導入が延期されてきました。 将来はこれをデフォルトでオンにしようと検討していますが、フィードバックがあればぜひお知らせ下さい。
型付きFinderパラメータ
テーブルの finder のパラメータは必須のものにすることができるようになりました。 例えばブログ記事の投稿をカテゴリまたはユーザで検索するメソッドは、以前はこのようなコードになりました:
public function findByCategoryOrUser(SelectQuery $query, array $options)
{
if (isset($options['categoryId'])) {
$query->where(['category_id' => $options['categoryId']]);
}
if (isset($options['userId'])) {
$query->where(['user_id' => $options['userId']]);
}
return $query;
}これが今では次のように書くことができます:
public function findByCategoryOrUser(SelectQuery $query, ?int $categoryId = null, ?int $userId = null)
{
if ($categoryId) {
$query->where(['category_id' => $categoryId]);
}
if ($userId) {
$query->where(['user_id' => $userId]);
}
return $query;
}この finder を呼び出す際は find('byCategoryOrUser', userId: $somevar) と書くことができます。 さらに、特別な名前付き引数を用いて、条件を追加することもできます。例えば find('byCategoryOrUser', userId: $somevar, conditions: ['enabled' => true]) のようになります。
同様の変更が RepositoryInterface::get() にも追加されました:
public function view(int $id)
{
$author = $this->Authors->get($id, [
'contain' => ['Books'],
'finder' => 'latest',
]);
}以前は上記のようなコードでしたが、今後は以下のようにも書けます:
public function view(int $id)
{
$author = $this->Authors->get($id, contain: ['Books'], finder: 'latest');
}TestSuite
- Integrationテストにおいて、次に発行するリクエストのヘッダに、JSON でやり取りする趣旨のヘッダを付与するメソッド
IntegrationTestTrait::requestAsJson()が追加されました。
Plugin Installer
- プラグインのインストーラが更新されて、プラグインのクラスの autoload を自動的に制御するようになりました。
composer.jsonから、名前空間とパスの対応関係マップを削除して、composer dumpautoloadを実行することでもプラグインを動作させられます。