PHP 8.3 は 2023 年 11 月 23 日にリリースされます; 読み取り専用クラスが改善されており、新しい json_validate() 機能、最近追加された機能への追加 Randomizer クラス、スタックオーバーフロー検出など。
この投稿では、すべての機能、パフォーマンスの向上、変更、非推奨について 1 つずつ説明します。 最新情報を入手したい場合は、ニュースレターを購読するか、Twitter でフォローするか、RSS フィードを購読してください。
# 読み取り専用の修正 RFC
この RFC は 2 つの変更を提案しましたが、クローン作成中に読み取り専用プロパティを再初期化できるようにするという 1 つだけが受け入れられました。 それは非常に大したことのように聞こえるかもしれませんが、この RFC は、非常に特殊な (しかし重要な) エッジケース、つまり、プロパティ値を上書きすることのみを扱っています。 __clone()ディープクローンの読み取り専用プロパティを許可するため。
readonly class Post
{
public function __construct(
public DateTime $createdAt,
) {}
public function __clone()
{
$this->createdAt = new DateTime();
// This is allowed,
// even though `createdAt` is a readonly property.
}
}
この RFC に関する詳細な投稿といくつかの補足をここで読むことができます。
# 型付きクラス定数 RFC
クラス定数をタイプヒントできるようになりました。
class Foo
{
const string BAR = 'baz';
}
# #(Override) 属性 RFC
新しい #(Override) 属性はプログラマの意図を示すために使用されます。 基本的には、「このメソッドが親メソッドをオーバーライドしていることはわかっています。変更される場合はお知らせください。」というものです。
以下に例を示します。
abstract class Parent
{
public function methodWithDefaultImplementation(): int
{
return 1;
}
}
final class Child extends Parent
{
#(Override)
public function methodWithDefaultImplementation(): int
{
return 2; // The overridden method
}
}
ここで、ある時点で親メソッドがそのメソッド名を変更すると想像してみましょう。
abstract class Parent
{
public function methodWithNewImplementation(): int
{
return 1;
}
}
おかげ #(Override) 属性を使用すると、PHP はそれを検出できます。 Child::methodWithDefaultImplementation() もう何もオーバーライドされず、エラーがスローされます。
詳細については、こちらをご覧ください。 #(Override) ここの属性。
# 配列内の負のインデックス 速報
空の配列がある場合は、 ネガティブ インデックスを作成してから別の項目を追加すると、その 2 番目の項目は常にインデックスから始まります。 0:
$array = ();
$array(-5) = 'a';
$array() = 'b';
var_export($array);
//array (
// -5 => 'a',
// 0 => 'b',
//)
PHP 8.3 以降、次の項目がインデックスに追加されます -4:
//array (
// -5 => 'a',
// -4 => 'b',
//)
# 匿名の読み取り専用クラス アップグレード中
以前は、匿名クラスを読み取り専用としてマークできませんでした。 これは PHP 8.3 で修正されています。
$class = new readonly class {
public function __construct(
public string $foo = 'bar',
) {}
};
# 新しい json_validate() 関数 RFC
以前は、文字列が有効な JSON であるかどうかを検証する唯一の方法は、文字列をデコードしてエラーがスローされたかどうかを検出することでした。 この新しい json_validate() この関数は、文字列をデコードする場合に比べてメモリ使用量が少ないため、入力が有効な JSON かどうかだけを知る必要がある場合に有益です。
json_validate(string $json, int $depth = 512, int $flags = 0): bool
# Randomizer 追加 RFC
PHP 8.2 では、新しい Randomizer クラスが追加されました。 このアップデートでは、いくつかの小さな追加が行われます。
Randomizer::getBytesFromString(string $string, int $length): string
このメソッドを使用すると、指定された文字列からランダムに選択されたバイトで構成される、指定された長さの文字列を生成できます。
Randomizer::getFloat(
float $min,
float $max,
IntervalBoundary $boundary = IntervalBoundary::ClosedOpen
): float
getFloat() 間の浮動小数点数を返します $min そして $max。 次のことを定義できます。 $min そして $max のおかげで含まれるはずです IntervalBoundary 列挙型。 Closed は値が含まれていることを意味しますが、 Open 除外されることを意味します。
Randomizer::nextFloat(): float {}
ついに、 nextFloat() の略記です getFloat(0, 1, IntervalBoundary::ClosedOpen)言い換えると、0 から 1 までのランダムな浮動小数点数が得られます (1 は除外されます)。
# 動的クラス定数の取得 RFC
PHP 8.3 では、より動的な構文で定数をフェッチできます。
class Foo
{
const BAR = 'bar';
}
$name = 'BAR';
// Instead of this:
constant(Foo::class . '::' . $name);
// You can now do this:
Foo::{$name};
# 適切な日付/時刻の例外がさらに増えました RFC 速報
多くの場合、PHP は単純に Exception または Error 物体; または、日付と時刻の処理で問題が発生した場合に警告またはエラーを発行します。 この RFC は、これらすべてのエッジケースを検討し、それらに対する適切な専用の例外を追加します。
現在、次のような例外があります DateMalformedIntervalStringException、 DateInvalidOperationException、 そして DateRangeError。
一般に、これらの追加はコードを壊すことはありません。なぜなら、これらの新しく追加された例外とエラーはジェネリック クラスのサブクラスだからです。 Exception そして Error クラス。 ただし、この RFC には 3 つの小さな重大な変更が含まれています。
- の
Epoch doesn't fit in a PHP integer新しいものを返しますDateRangeErrorジェネリックの代わりにValueError、サブクラス化されません。 これは 32 ビット プラットフォームのみの問題です。 - の
Only non-special relative time specifications are supported for subtraction警告付きDateTime::sub()そしてdate_sub()新しいものになるDateInvalidOperationException。 - の
Unknown or bad format (%s) at position %d (%c): %sそしてString '%s' contains non-relative elements間違った/壊れた解析中に作成される警告DateInterval文字列は新しいものをスローするようになりますDateMalformedIntervalStringExceptionOO インターフェイスで使用すると、警告を表示して false を返す代わりに。
# 改善されました unserialize() エラー処理 RFC
unserialize() 常に を発行するようになりました E_WARNING 問題に遭遇したときではなく、 E_NOTICE。
この RFC では、実行時にさらに例外を追加することも提案されています。 unserialize()、しかしその部分は受け入れられませんでした。
# への変更 range() 関数 速報
変更ログから:
- あ
TypeErrorオブジェクト、リソース、または配列を境界入力として渡すときにスローされるようになりました - より説明的な
ValueErrorに 0 を渡すとスローされます$step - あ
ValueErrorマイナスを使用するとスローされるようになりました$step範囲を広げるために - もし
$stepは int として解釈できる float ですが、現在はそうされています - あ
ValueError引数があればスローされるようになりました。infinityまたはNAN - アン
E_WARNINGの場合に出力されるようになりました$startまたは$endは空の文字列です。 値は引き続き値 0 にキャストされます。 - アン
E_WARNINGの場合に出力されるようになりました$startまたは$end数値以外の文字列の場合のみ、複数のバイトが含まれます。 - アン
E_WARNINGの場合に出力されるようになりました$startまたは$end他の境界入力は数値であるため、整数にキャストされます。 (例えばrange(5, 'z');) - アン
E_WARNING両方の境界入力が数値文字列である場合を除き、文字範囲を生成しようとするときに $step が浮動小数点数の場合に出力されるようになりました (例:range('5', '9', 0.5);警告は生成されません) -
range()境界入力の 1 つが文字列数字の場合、もう一方の入力を int にキャストする代わりに、文字のリストを生成するようになりました (例:range('5', 'z');)
# 特性と静的プロパティ 速報
変更ログから:
静的プロパティを持つ特性を使用すると、親クラスから継承された静的プロパティが再宣言されるようになります。 これにより、現在のクラス用に別の静的プロパティ ストレージが作成されます。 これは、特性を使用せずに静的プロパティをクラスに直接追加することに似ています。
# スタックオーバーフロー検出 PR
PHP 8.3 では、次の 2 つの新しい ini ディレクティブが追加されています。 zend.max_allowed_stack_size そして zend.reserved_stack_size。 コールスタックがオーバーフローしそうになったプログラムは、 Error の差以上を使用する場合 zend.max_allowed_stack_size そして zend.reserved_stack_size。
この機能の利点は、スタック オーバーフローによって引き起こされるセグメンテーション フォールトがセグメンテーション フォールトを引き起こさなくなり、デバッグが大幅に容易になることです。
のデフォルト zend.max_allowed_stack_size は 0つまり、PHP が値を自動的に決定します。 ご提供することもできます -1 制限がないこと、または特定のバイト数がないことを示します。 の zend.reserved_stack_size ディレクティブは「バッファーゾーン」を決定するために使用されるため、PHP は実際にメモリ不足にならずにエラーをスローできます。 ここの値はバイト数である必要がありますが、PHP が適切なデフォルトを決定するため、特定のプログラムの特殊なケースに遭遇しない限り、必ずしも設定する必要はありません。
最後に、繊維については、既存の fiber.stack_size ディレクティブは、最大許容スタック サイズとして使用されます。
zend.max_allowed_stack_size=128K
# 新しい mb_str_pad 関数 RFC
RFC より:
PHP では、さまざまな文字列関数が 2 つのバージョンで使用できます。1 つはバイト文字列用、もう 1 つはマルチバイト文字列用です。 ただし、マルチバイト文字列関数の中に注目すべき欠如があるのは、
mbstringと同等のstr_pad()。 のstr_pad()関数にはマルチバイト文字のサポートがないため、UTF-8 などのマルチバイト エンコーディングを使用する言語を使用する場合に問題が発生します。 この RFC は、そのような関数を PHP に追加することを提案しています。mb_str_pad()。
関数は次のようになります。
function mb_str_pad(
string $string,
int $length,
string $pad_string = " ",
int $pad_type = STR_PAD_RIGHT,
?string $encoding = null,
): string {}
# マジック メソッド クロージャと名前付き引数 PR
マジック メソッドをサポートするクラスがあるとします。
class Test {
public function __call($name, $args)
{
var_dump($name, $args);
}
public static function __callStatic($name, $args) {
var_dump($name, $args);
}
}
PHP 8.3 では、これらのメソッドからクロージャを作成し、名前付き引数をそれらのクロージャに渡すことができます。 以前はそんなことは不可能でした。
$test = new Test();
$closure = $test->magic(...);
$closure(a: 'hello', b: 'world');
# 不変の定数可視性 速報
以前は、インターフェイスの実装時に定数の可視性がチェックされませんでした。 PHP 8.3 ではこのバグが修正されていますが、この動作を認識していなかった場合、場所によってはコードが中断される可能性があります。
interface I {
public const FOO = 'foo';
}
class C implements I {
private const FOO = 'foo';
}
# 小さな非推奨の RFC rfc
どのリリースでも通常のことですが、多数の小さな非推奨事項を追加する 1 つの RFC があります。 非推奨は間違いではなく、一般に言語を前進させるには良いことであることに留意してください。 これらは通過した非推奨です。詳細については、RFC を参照してください。
- 負の値の受け渡しを廃止する
$widthsにmb_strimwidth() - 非推奨にして削除する
NumberFormatter::TYPE_CURRENCY絶え間ない - 壊れた PHP 7.1 以前の Mt19937 実装を非推奨にし、削除します (
MT_RAND_PHP) - 呼び出しを非推奨にして削除する
ldap_connect()2つのパラメータを使用して$hostそして$port -
文字列評価されたコード アサーションの残りを非推奨にする
# 小さいですが注目に値する変更
PHP のすべての変更が RFC プロセスを通過するわけではありません。 実際、変更の大部分にはメンテナンスとバグ修正が含まれており、RFC は必要ありません。 これらの変更はすべて、アップグレードに関するドキュメントに記載されています。 最も有名なものをいくつかリストしますが、最も細かい詳細について知りたい場合は、リスト全体を必ず読んでください。
- FFI を使用する場合、戻り値の型が次の C 関数です。
void今戻りますnull返す代わりにFFI\CData:void -
posix_getrlimit()オプションで取得できるようになりました$resパラメータを使用して、単一のリソース制限を取得できるようにします。 -
gc_status()4 つの新しいフィールドがあります。running、protected、full、 そしてbuffer_size。 -
class_alias()内部クラスのエイリアスの作成をサポートするようになりました。 -
mysqli_poll()今はValueError読み取り引数またはエラー引数が渡されたとき。 -
array_pad()は、配列が持つことができる要素の最大数によってのみ制限されるようになりました。 以前は、一度に最大 1048576 個の要素しか追加できませんでした。 - 新しい posix 関数:
posix_sysconf()、posix_pathconf()、posix_fpathconf()、 そしてposix_eaccess() - 実行中
proc_get_status()posix システムでは、複数回実行すると常に正しい値が返されるようになりました。 -
opcache.consistency_checksini ディレクティブが削除されました -
改善されました
array_sum()そしてarray_product()
現時点ではこれで終わりですが、このリストは時間の経過とともに増加します。 最新情報を入手したい場合は、ニュースレターを購読するか、Twitter でフォローするか、RSS フィードを購読してください。