PHP の新しいメジャー バージョンである PHP8 は、2020 年末までにリリースされる予定です。
現在、非常に活発な開発が行われているため、開発のペースと進捗状況は今後数か月で大幅に変化する可能性があります。
この記事では、PHP8 で行われる変更点のいくつか (新機能、パフォーマンスの向上、重大な変更) をリストします。
PHP8 は新しいメジャー バージョンであるため、コードと構文の下位互換性は低くなります。
最新のリリースを常に最新の状態に保っている場合、ほとんどの重大な変更は 7.* リリースで非推奨になっているため、アップグレードはそれほど難しくありません。
PHP8 には、画期的な変更に加えて、JIT コンパイラーや共用体型などのいくつかの優れた新機能も導入されており、もちろん他にも多くの機能があります。
新機能
新機能から始めますが、PHP8 はまだ活発に開発中であるため、このリストは時間の経過とともに増加するでしょう。
共用体タイプ (共用体タイプ) RFC
PHP の動的型付けの性質を考慮すると、共用体タイプは多くの状況で役立ちます。
共用体型は、どちらの型も使用できることを示す 2 つ以上の型のコレクションです。
public function foo(Foo|Bar $input): int|float;
これが C 言語の Union に似ていると思うのはなぜですか。
void は「戻り値がまったくない」ことを意味するため、共用体型の一部にはできないことに注意してください。
また、|NULL を使用することも、既存のものを使用することもできますか? 。
public function foo(Foo|null $foo): void; public function bar(?Bar $bar): void;
JIT RFC
JIT-Just-In-Time コンパイラーは、Web アプリケーションでは大きなメリットがない可能性がありますが、パフォーマンスの大幅な向上を約束します。
現時点では正確なベンチマークはありませんが、必ず出現するでしょう。
静的な戻り値の型 (静的な戻り値の型) RFC
すでに self を返すことが可能ですが、PHP8 より前では static は有効な戻り値の型ではありませんでした。 PHP は、動的に型付けされる性質を考慮すると、多くの開発者にとって役立ちます。
class Foo { public function test(): static { return new static(); } }
弱いマップ RFC
PHP 7.4 で追加された WeakRefs RFC に基づいて、WeakMap 実装が PHP 8 に追加されました。 WeakMap にはオブジェクトへの参照が含まれていますが、これらのオブジェクトがガベージ コレクションされることは妨げられません。
ORM を例に挙げると、多くの場合、ORM はエンティティ間の関係のパフォーマンスを向上させるために、エンティティ クラスへの参照を含むキャッシュを実装します。
これらのエンティティ オブジェクトは、キャッシュがエンティティ オブジェクトを参照している唯一のものであっても、キャッシュに参照がある限りガベージ コレクションできません。
このキャッシュ層が代わりに弱い参照とマッピングを使用する場合、PHP は、これらのオブジェクトが他のオブジェクトによって参照されなくなったときにガベージ コレクションを実行します。
特に、単一のリクエストで数百 (数千ではないにしても) のエンティティを管理できる ORM の場合、弱いマッピングを使用すると、これらのオブジェクトを処理するための、より適切でリソースに優しい方法を提供できます。
次に、弱いマップの使用法 (RFC の例) を示します。
class Foo { private WeakMap $cache; public function getSomethingWithCaching(object $obj): object { return $this->cache[$obj] ??= $this->computeSomethingExpensive($obj); } }
オブジェクトで使用できます::class RFC
小さいながらも便利な新機能: get_class() を使用しなくても、オブジェクトに対して ::class を使用できるようになりました。
これは get_class() と同じように機能します。
$foo = new Foo(); var_dump($foo::class);
DateTime オブジェクトを作成するためのインターフェイス
DateTime::createFromImmutable($immutableDateTime) を使用して DateTimeImmutable オブジェクトから DateTime オブジェクトを作成することはすでに可能ですが、その逆は注意が必要です。 。
DateTime::createFromInterface() と DatetimeImmutable::createFromInterface() の追加により、DateTime オブジェクトと DateTimeImmutable オブジェクトを相互に変換する汎用的な方法が利用できるようになりました。
DateTime::createFromInterface(DateTimeInterface $other); DateTimeImmutable::createFromInterface(DateTimeInterface $other);
新しい Stringable インターフェイス RFC
Stringable インターフェイスを使用して、任意の文字列を入力したり、__toString() を実装したりできます。
また、クラスが __toString() を実装するときは常に、バックグラウンドでインターフェイスが自動的に実装されるため、手動で実装する必要はありません。
class Foo { public function __toString(): string { return 'foo'; } } function bar(Stringable $stringable) { /* … */ } bar(new Foo()); bar('abc');
新しい str_contains () 関数 RFC
これは長い間遅れていると言う人もいるかもしれませんが、ついに strpos () に依存する必要がなくなりました。 string には別の文字列が含まれています。
以前:
if (strpos('string with lots of words', 'words') !== false) { /* … */ }
現在:
if (str_contains('string with lots of words', 'words')) { /* … */ }
新しい fdiv () 関数 PR
新しい fdiv () 関数 次と同様に動作します。 fmod () 関数と intdiv () 関数。これらはゼロで割り切れます。
場合に応じて、エラーの代わりに INF、-INF、または NaN が返されます。
新しい get_debug_type () 関数 RFC
get_debug_type () は変数の型を返します。
gettype() で何かできるようですね。
get_debug_type () は、配列、文字列、匿名クラス、オブジェクトに関するより有用な出力を返します。
たとえば、クラス \foo\Bar で gettype() を呼び出すと、Object が返されます。
get_debug_type() を使用すると、クラス名が返されます。
get_debug_type () と gettype () の違いの完全なリストは、RFC にあります。
特性の抽象メソッドの改善 RFC
特性では、それを使用するクラスによって実装される必要がある抽象メソッドを指定できます。
ただし、警告があります。PHP8 より前では、これらのメソッド実装の署名は検証されていませんでした。
在以下代码中有效:
trait Test { abstract public function test(int $input): int; } class UsesTrait { use Test; public function test($input) { return $input; } }
在使用 traits 并实现其抽象方法时,PHP8 将执行正确的方法签名验证。
这意味着您需要改写以下内容:
class UsesTrait { use Test; public function test(int $input): int { return $input; } }
token_get_all () 的对象接口 RFC
函数的作用是:返回值的是一个数组。
此 RFC 使用 PhpToken::getall () 方法添加一个 PhpToken 类。
此实现使用对象,而不是普通值。
它消耗更少的内存,更容易阅读。
变量语法调整 RFC
来自 RFC:“统一变量语法 RFC 解决了 PHP 变量语法中的一些不一致问题”,这个 RFC 打算解决少数被忽略的情况。
内部函数的类型批注
很多人都参与到为所有内部函数添加适当类型注释的工作中。
这是一个长期存在的问题,通过在以前版本中对 PHP 所做的所有更改,最终可以解决这个问题。
这意味着内部函数和方法在反射中将具有完整的类型信息。
统一错误类型 RFC
PHP 中的用户定义函数已经抛出 TypeErrors,但是内部函数没有抛出 TypeErrors,而是发出警告并返回 NULL。
从 PHP8 开始,内部函数的行为已经保持一致。
重新分类 zend engine 报错 RFC
许多以前只触发警告或通知的错误已转换为适当的错误。
以下警告已更改。
未定义变量:错误异常而不是通知。
未定义的数组索引:警告而不是通知。
被零除:DivisionByZeroError 异常而不是警告。
尝试递增 / 递减非对象的属性‘% s’:错误异常而不是警告。
试图修改非对象的属性‘% s’:错误异常而不是警告。
尝试分配非对象的属性‘% s’:错误异常而不是警告。
从空值创建默认对象:错误异常而不是警告。
正在尝试获取非对象的属性‘% s’:警告而不是通知。
未定义属性:% s::$% s:警告而不是通知。
无法将元素添加到数组,因为下一个元素已被占用:错误异常而不是警告。
无法取消设置非数组变量中的偏移量:错误异常而不是警告。
不能将标量值用作数组:错误异常而不是警告。
只能解包数组和遍历:TypeError 异常而不是警告。
为 foreach () 提供的参数无效:TypeError 异常而不是警告。
偏移类型非法:TypeError 异常而不是警告。
isset 中的偏移类型非法或为空:TypeError 异常而不是警告。
未设置中的偏移类型非法:TypeError 异常而不是警告。
数组到字符串的转换:警告而不是通知。
资源 ID#% d 用作偏移量,转换为整数 (% d):警告而不是通知。
发生字符串偏移量转换:警告而不是通知。
未初始化的字符串偏移量:% d:警告而不是通知。
无法将空字符串分配给字符串偏移量:错误异常而不是警告
默认错误报告级别
现在是 E_ALL,而不是除 E_NOTICE 和 E_DEVERATED 之外的所有内容。
这意味着可能会弹出许多以前被悄悄忽略的错误,尽管在 PHP8 之前可能已经存在。
@运算符不再忽略致命错误
此更改可能会揭示在 PHP8 之前隐藏的错误。请确保在生产服务器上设置 display_errors=off !
串联优先级 RFC
虽然在 PHP7.4 中已不推荐使用,但此更改现在生效。
如果你这样写的话:
echo "sum: " . $a + $b;
PHP 以前会这样解释它:
echo ("sum: " . $a) + $b;
PHP 8 将会这样解释它:
echo "sum: " . ($a + $b);
反射方法签名更改
反射类的三个方法签名已更改:
ReflectionClass::newInstance($args); ReflectionFunction::invoke($args); ReflectionMethod::invoke($object, $args);
现已成为:
ReflectionClass::newInstance(...$args); ReflectionFunction::invoke(...$args); ReflectionMethod::invoke($object, ...$args);
升级指南指定,如果您扩展了这些类,并且仍然希望同时支持 PHP 7 和 PHP 8,则允许以下签名:
ReflectionClass::newInstance($arg = null, ...$args); ReflectionFunction::invoke($arg = null, ...$args); ReflectionMethod::invoke($object, $arg = null, ...$args);
推荐教程:《PHP教程》
以上がPHP 8 は半年後に登場します。どのような新機能があるのか見てみましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。