PHP 8.2 の新機能 – 新機能、廃止予定、変更点など

PHP 8.2 の新機能 – 新機能、廃止予定、変更点など

PHP 8.2は、PHP 8.0とPHP 8.1によって確立された新たな基盤の上に構築されています。PHP8.2がリリースされたので、PHP8.2の新機能や改善点から、非推奨の機能やマイナーな変更点まで、PHP8.2の新機能を詳しくKinstaがまとめているのでそれを参考にしてます。

PHP 8.2 の新機能と改善点

まずは、PHP 8.2 の最新機能をすべて見てみましょう。かなり広範囲なリストです:

新しい readonly クラス

PHP 8.1 では、クラスプロパティの readonly 機能が導入されました。現在、PHP 8.2 ではクラス全体を readonly として宣言するサポートが追加されています。

クラスをreadonlyとして宣言すると、そのすべてのプロパティは自動的にreadonly機能を継承します。したがって、クラスを readonly と宣言することは、すべてのクラスのプロパティを readonly と宣言することと同じです。

true、false、null をスタンドアロン型として許可する


PHP には、int 型、string 型、bool 型などのスカラー型があります。PHP8.0ではユニオン型が追加され、異なる型の値を指定できるようになりました。同じRFCでは、falseやnullをユニオン型の一部として使用することも認められています。

もし、falseやnullをユニオン型の一部としてではなく、単独の型として宣言しようとすると、致命的なエラーになります。

function spam(): null {}。
関数eggs(): false {}。

致命的なエラー: Null はスタンドアロン型として使用できません。
致命的なエラー: Fatal error: False は、… 行の … で単独の型として使用できません。
このシナリオを回避するために、PHP 8.2ではfalseとnullをスタンドアロン型として使用できるようになりました。この追加により、PHP の型システムはより表現力豊かで完全なものになります。戻り値、パラメータ、プロパティの型を正確に宣言できるようになりました。

また、PHPにはまだtrue型がありません。これは、false型の自然な対になるものと思われます。PHP 8.2ではそれが修正され、true型のサポートも追加されました。これは、false型の振る舞いとまったく同じで、強制はできません。

true型もfalse型も、本質的にはPHPのbool型のユニオン型です。冗長性を避けるために、これらの3つの型を一緒にユニオン型で宣言することはできません。これを行うと、コンパイル時に致命的なエラーが発生します。

分離正規形 (DNF) 型

分離正規形(DNF)は、ブール式を整理する標準的な方法です。DNFは接続詞の論理和で構成され、ブール式で言えばANDのORです。

DNFを型宣言に適用することで、パーサが扱えるUnion型とIntersection型を組み合わせた標準的な書き方ができるようになります。PHP 8.2 の新機能である DNF 型は、適切に使用すればシンプルかつ強力です。

バックトレースにおけるセンシティブなパラメータの再編集

ほぼすべてのプログラミング言語と同様に、PHP ではコードの実行中のどの時点でもコールスタックをトレースすることができます。スタックトレースは、エラーやパフォーマンスのボトルネックを修正するために コードをデバッグすることを容易にします。スタックトレースは、WordPressサイト用にカスタム設計されたパフォーマンスモニタリングツールのバックボーンを形成します。

スタックトレースを実行しても、プログラムの実行は停止しません。通常、ほとんどのスタックトレースはバックグラウンドで実行され、静かにログに記録されます。

しかし、これらの詳細な PHP スタックトレースの一部は、サードパーティのサービス(通常はエラーログ分析、 エラー追跡など)と共有すると、欠点になる可能性があります。これらのスタックトレースには、ユーザ名やパスワード、環境変数などの機密情報が含まれる可能性があります。

新しい mysqli_execute_query 関数と mysqli::execute_query メソッド

パラメータ化された MySQLi クエリを実行するために mysqli_query() 関数を使用したことがありますか?

PHP 8.2 では、新しい mysqli_execute_query($sql, $params) 関数と mysqli::execute_query メソッドにより、パラメータ化された MySQLi クエリを簡単に実行できるようになりました。

基本的に、この新しい関数は mysqli_prepare()、 mysqli_execute()、そして mysqli_stmt_get_result() 関数を組み合わせたものです。この関数を使用すると、MySQLi クエリが準備され、(パラメータを渡した場合は) バインドされ、関数内で実行されます。クエリが正常に実行されると、 mysqli_result オブジェクトが返されます。失敗した場合は false を返します。

const 式での enum プロパティの取得

この RFC では、->/?-> 演算子を使って const 式で enum プロパティを取得できるようにすることを提案しています。

この新機能の主な理由は、配列のキーのように enum オブジェクトを使用できない場所があることです。そのような場合、enumケースを使用するためだけに、その値を繰り返さなければならなくなります。

enumオブジェクトが許可されていない場所でもenumプロパティのフェッチを許可することで、この手順を簡略化することができる。

Traits での定数の使用

PHP には Traits と呼ばれるコードの再利用方法があります。これは、クラス間でコードを再利用するのに便利です。

現在のところ、Trait で定義できるのはメソッドとプロパティだけで、 定数は定義できません。つまり、ある Trait が期待する不変量を Trait 自身で定義することはできないということです。この制限を回避するには、Trait を構成するクラスか、Trait を構成するクラスが実装するインタフェースで定数を定義する必要があります。

この RFC では、Trait 内で定数を定義できるようにすることを提案しています。これらの定数は、クラス定数を定義するのと同じように定義できます。

Trusted SSL from just $3.44

PHP 8.2 における非推奨事項

ここで、PHP 8.2 のすべての非推奨項目について調べることにしましょう。このリストは、新機能ほど大きくはありません:

動的プロパティの廃止 (そして新しい #[AllowDynamicProperties] 属性)

PHP 8.1 までは、宣言されていないクラスのプロパティを動的に設定したり取得したりすることができました。たとえば

部分的にサポートされる callables の非推奨化

PHP 8.2 のもうひとつの変更点は、影響はごくわずかですが 部分的にサポートされる callable を非推奨とすることです。

これらの callable は、$callable() で直接操作することができないため、部分的にサポートされています。call_user_func($callable)関数を使用することでしか呼び出すことができません。このような callable のリストは長くありません:

"self::method"
"parent::method"
"static::method"
["self", "method"] ["parent", "method
["parent", "method"] ["static", "method
"static", "method"] ["static", "method
["Foo", "Bar::method"]。
[new Foo, "Bar::method"] 

となります。
PHP 8.2 以降では、このような callable を call_user_func() や array_map() 関数で呼び出そうとすると、非推奨の警告が表示されます。

オリジナルのRFCには、この非推奨の確かな理由が書かれています:

最後の2つのケースを除けば、これらの callable はすべてコンテキスト依存である。self::method “が参照するメソッドは、呼び出しや呼び出し可能性チェックがどのクラスから実行されるかに依存します。実際には、[new Foo, “parent::method”]の形で使用される場合、これは最後の2つのケースにも当てはまります。

callable のコンテキスト依存を減らすことが、このRFCの第二の目標です。このRFCの後、まだ残っている唯一のスコープ依存は、メソッドの可視性です: 「Foo::bar “はあるスコープでは見えるかもしれませんが、別のスコープでは見えません。Foo::bar」は、あるスコープでは見えるかもしれませんが、別のスコープでは見えません。もし将来、callableがパブリック・メソッドに限定されるなら(一方、プライベート・メソッドは、ファーストクラスのcallableを使うか、Closure::fromCallable()を使ってスコープに依存しないようにしなければなりません)、callable型は明確に定義されるようになり、プロパティ型として使えるようになるでしょう。しかし、このRFCの一部として、可視性の処理の変更は提案されていません。

元のRFCに従って、is_callable()関数と callable型は、これらの callableを例外として受け入れ続けます。ただし、PHP 9.0 以降でこれらのサポートが完全に削除されるまでです。

混乱を避けるために、この非推奨の通知の範囲が新しい RFC で拡張されました。

PHP が明確に定義された callable 型を持つようになるのは良いことです。

関数 #utf8_encode() および utf8_decode() の非推奨化

PHP の組み込み関数 utf8_encode() および utf8_decode() は、 ISO-8859-1 (“Latin 1”) でエンコードされた文字列を UTF-8 に変換します。

しかし、これらの関数の名前は、その実装が許すよりも一般的な使い方を示唆しています。Latin 1″ エンコーディングは、”Windows Code Page 1252″ のような他のエンコーディングとよく混同されます。

さらに、これらの関数が文字列を正しく変換できないときは、たいていモジバケを見ることになる。エラーメッセージが表示されないということは、 エラーを見つけるのが難しいということでもあります。

PHP 8.2 では、#utf8_encode() 関数と utf8_decode() 関数の両方が非推奨となっています。これらの関数を呼び出すと、非推奨の通知が表示されます:

非推奨: 関数utf8_encode()は非推奨です。
非推奨: 関数 utf8_decode() は非推奨です。
RFC では、PHP がサポートしている mbstring や iconv、intl といった拡張モジュールを使用することを推奨しています。

非推奨 ${} 文字列補間

PHP では、ダブルクォート (“) や heredoc (<<<) を使って文字列中に変数を埋め込むことができます:

  1. 変数を直接埋め込む – “$foo”
  2. 変数の外側に中括弧をつける – “{$foo}”
  3. ドル記号の後に中括弧を付ける – “${foo}”
  4. 変数 – “${expr}” – (文字列) ${expr}を使うのと同じ。

最初の2つの方法には長所と短所がありますが、後の2つの方法は複雑で矛盾した構文を持っています。PHP 8.2 では、最後の2つの文字列補間の方法は非推奨となっています。

今後は、この方法で文字列を補間することは避けるべきです:

“こんにちは、${world}!”;
非推奨: 文字列で${}を使うのは非推奨です。

“こんにちは、${(world)}!”;
非推奨: 文字列での ${} (変数変数) の使用は非推奨です。
PHP 9.0 以降、これらの非推奨は例外エラーをスローするようにアップグレードされます。

Base64/QPrint/Uuencode/HTML エンティティ用の mbstring 関数の非推奨化

PHP の mbstring (マルチバイト文字列) 関数は、 Unicode や HTML エンティティ、その他のレガシーなテキストエンコーディングを扱う際に役立ちます。

しかし、Base64、Uuencode および QPrint はテキストエンコーディングではありません。PHP には、これらのエンコーディングの個別の実装も含まれています。

HTML エンティティに関しては、PHP には htmlspecialchars() および htmlentities() という組み込み関数があり、これらをよりうまく扱うことができます。たとえば、mbstring とは異なり、これらの関数は <. >や&文字もHTMLエンティティに変換します。

さらに、PHPは常に組み込み関数を改良しています。PHP 8.1のHTMLエンコード/デコード関数のように。

そのため、PHP 8.2 ではこれらのエンコーディングにおける mbstring の使用を廃止します (ラベルは大文字小文字を区別しません):

BASE64
UUENCODE
HTML-ENTITIES
html (HTML-ENTITIES のエイリアス)
引用符付き印刷可能
qprint (Quoted-Printable のエイリアス)
PHP 8.2 以降では、mbstring を使用して上記のいずれかをエンコード/デコードすると 非推奨の通知が表示されます。PHP 9.0 では、これらのエンコーディングの mbstring サポートは完全に削除されます。

PHP 8.2 におけるその他のマイナーな変更点

最後に、PHP 8.2 のマイナーな変更点について説明します。

mysqli からの libmysql サポートの削除

現在のところ、PHP では mysqli ドライバと PDO_mysql ドライバの両方が mysqlnd ライブラリと libmysql ライブラリに対してビルドできるようになっています。しかし、PHP 5.4 以降のデフォルトドライバおよび推奨ドライバは mysqlnd です。

これらのドライバには多くの利点と欠点があります。しかし、どちらか一方のサポートを削除することで、理想的には libmysql を削除することで、PHP のコードやユニットテストをシンプルにすることができます。

この利点を主張するために、RFC は mysqlnd の多くの利点を列挙しています:

  • PHP にバンドルされている
  • PHP のメモリ管理を使用してメモリ使用量を監視し
  • パフォーマンスの向上
  • クオリティオブライフ関数を提供する (例 get_result())
  • PHP ネイティブ型を使用して数値を返します。
  • 外部ライブラリに依存しない。
  • オプションのプラグイン機能
  • 非同期クエリをサポートする

RFC では、libmysql の利点として以下のようなものも挙げています:

  • 自動再接続が可能 ( mysqlnd はこの機能を意図的にサポートしていません。 悪用されやすいからです)。
  • LDAP および SASL 認証モード(mysqlnd は近いうちにこの機能も追加するかもしれない)。

PHPのメモリモデルとの非互換性、多くのテストの失敗、 メモリリーク、バージョン間の機能の違いなどです。

これらのことを考慮し、PHP 8.2 では libmysql に対して mysqli をビルドするサポートを削除しました。

libmysql でのみ使用可能な機能を追加したい場合は、 機能リクエストとして mysqlnd に明示的に追加する必要があります。また、自動再接続を追加することはできません。

ロケールに依存しない大文字小文字変換

PHP 8.0 より前のバージョンでは、PHP のロケールはシステム環境から継承していました。しかし、これはいくつかのエッジケースで問題を引き起こす可能性がありました。

Linux をインストールする際に言語を設定すると、組み込みコマンドに適切なユーザーインターフェイス言語が設定されます。しかし、Cライブラリの文字列処理機能の動作が予期せず変更されることもある。

たとえば、Linuxのインストール時に “トルコ語” あるいは “カザフ語” を選択した場合、大文字に相当する文字列を取得するために toupper(‘i’) をコールすると、ドット付きの大文字 I (U+0130, İ) が取得されます。

PHP 8.0 では、ユーザーが setlocale() で明示的に変更しない限りデフォルトのロケールを “C” に設定することで、この異常を回避しました。

PHP 8.2 ではさらに進んで、大文字小文字の変換からロケールの区別をなくしました。この RFC では、主に strtolower()、 strtoupper() および関連する関数を変更します。影響を受ける関数の一覧は RFC を参照ください。

ローカライズされた大文字小文字変換を使用したい場合は、mb_strtolower() を使用してください。

ランダム拡張の改善

PHP はランダム機能のオーバーホールを計画しています。

現在のところ、PHP のランダム機能は Mersenne Twister の状態に大きく依存しています。しかし、この状態は PHP のグローバル領域に暗黙のうちに保存されており、 ユーザがアクセスすることはできません。最初の播種段階から使用するまでの間にランダム化関数を追加すると、 コードが壊れてしまいます。

そのようなコードを維持するのは、外部パッケージを使用している場合は さらに複雑になります。

したがって、PHPの現在のランダム関数は、ランダムな値を一貫して再現することはできません。TestU01のCrushやBigCrushのような一様乱数生成器の経験的な統計テストにさえ失敗します。Mersenne Twisterの32ビット制限がさらにこの問題を悪化させています。

したがって、暗号的に安全な乱数が必要な場合は、 PHPの組み込み関数であるshuffle()、 str_shuffle()、 array_rand()を使用することは推奨されません。そのような場合は、random_int() や同様の関数を使用して新しい関数を実装する必要があります。

しかし、投票開始後にこの RFC に関するいくつかの問題が提起されました。このため、PHP チームはすべての問題を別の RFC にまとめ、 それぞれの問題ごとに投票オプションを作成することになりました。今後については、コンセンサスが得られた後に決定されます。

PHP 8.2の追加RFC

PHP 8.2 では、多くの新機能や細かな変更も行われています。

結論

PHP 8.2は、PHP 8.0およびPHP 8.1での大規模な改良の上に構築されています。PHP 8.2 の最もエキサイティングな機能は、新しいスタンドアロン型、 リードオンリープロパティ、そして数多くのパフォーマンスの改善だと思います。

その他

参考:Kinsta

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

お買い物カゴ