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/Command
Console/Shell
Controller/Component
Controller/Controller
Mailer/Mailer
View/Cell
View/Helper
View/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
を実行することでもプラグインを動作させられます。