Released!
PHP 8.0 は、PHP 言語のメジャーアップデートです。
このアップデートには、たくさんの新機能や最適化が含まれています。 たとえば 名前付き引数、 union 型、アトリビュート、コンストラクタでのプロパティのプロモーション、match 式、nullsafe 演算子、JIT、型システムの改善、エラーハンドリング、一貫性の向上などです。

名前付き引数 RFC

PHP 7
htmlspecialchars($string, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);
PHP 8
htmlspecialchars($string, double_encode: false);
  • 必須の引数だけを指定し、オプションの引数はスキップしています。
  • 引数の順番に依存せず、自己文書化(self-documented)されています。

アトリビュート RFC Doc

PHP 7
class PostsController
{
/**
* @Route("/api/posts/{id}", methods={"GET"})
*/
public function get($id) { /* ... */ }
}
PHP 8
class PostsController
{
#[
Route("/api/posts/{id}", methods: ["GET"])]
public function
get($id) { /* ... */ }
}

PHPDoc のアノテーションの代わりに、PHP ネイティブの文法で構造化されたメタデータを扱えるようになりました。

コンストラクタでの、プロパティのプロモーション RFC Doc

PHP 7
class Point {
public
float $x;
public
float $y;
public
float $z;

public function
__construct(
float $x = 0.0,
float $y = 0.0,
float $z = 0.0
) {
$this->x = $x;
$this->y = $y;
$this->z = $z;
}
}
PHP 8
class Point {
public function
__construct(
public
float $x = 0.0,
public
float $y = 0.0,
public
float $z = 0.0,
) {}
}

ボイラープレートのコードを減らすため、コンストラクタでプロパティを定義し、初期化します。

Union 型 RFC Doc

PHP 7
class Number {
/** @var int|float */
private $number;

/**
* @param float|int $number
*/
public function __construct($number) {
$this->number = $number;
}
}

new
Number('NaN'); // Ok
PHP 8
class Number {
public function
__construct(
private
int|float $number
) {}
}

new
Number('NaN'); // TypeError

PHPDoc のアノテーションを使って型を組み合わせる代わりに、実行時に検証が行われる union型 をネイティブで使えるようになりました。

Match 式 RFC Doc

PHP 7
switch (8.0) {
case
'8.0':
$result = "Oh no!";
break;
case
8.0:
$result = "This is what I expected";
break;
}
echo
$result;
//> Oh no!
PHP 8
echo match (8.0) {
'8.0' => "Oh no!",
8.0 => "This is what I expected",
};
//> This is what I expected

match は switch 文に似ていますが、以下の機能があります:

  • match は式なので、結果を返したり、変数に保存したりできます。
  • match の分岐は一行の式だけをサポートしており、break; 文は不要です。
  • match は、型と値について、厳密な比較を行います。

Nullsafe 演算子 RFC

PHP 7
$country = null;

if (
$session !== null) {
$user = $session->user;

if (
$user !== null) {
$address = $user->getAddress();

if (
$address !== null) {
$country = $address->country;
}
}
}
PHP 8
$country = $session?->user?->getAddress()?->country;

null チェックの条件を追加する代わりに、nullsafe演算子 を使って呼び出しをチェインさせられるようになりました。呼び出しチェインのひとつが失敗すると、チェインの実行全体が停止し、null と評価されます。

数値と文字列の比較 RFC

PHP 7
0 == 'foobar' // true
PHP 8
0 == 'foobar' // false

数値形式の文字列と比較する場合は、PHP 8 は数値として比較を行います。それ以外の場合は、数値を文字列に変換し、文字列として比較を行います。

内部関数の型に関するエラーが一貫したものに RFC

PHP 7
strlen([]); // Warning: strlen() expects parameter 1 to be string, array given

array_chunk([], -1); // Warning: array_chunk(): Size parameter expected to be greater than 0
PHP 8
strlen([]); // TypeError: strlen(): Argument #1 ($str) must be of type string, array given

array_chunk([], -1); // ValueError: array_chunk(): Argument #2 ($length) must be greater than 0

ほとんどの内部関数は、引数の検証に失敗すると Error 例外をスローするようになりました。

JIT (ジャストインタイム) コンパイル

PHP 8 は JITコンパイル のエンジンをふたつ搭載しています。 トレーシングJITは、もっとも有望なふたつの人工的なベンチマークで、 約3倍のパフォーマンスを示しました。 また、長期間動いている特定のあるアプリケーションでは、1.5-2倍のパフォーマンス向上が見られました。 典型的なアプリケーションのパフォーマンスは、PHP 7.4 と同等でした。

PHP 8 のパフォーマンスに対するJITの貢献

Just-In-Time compilation

型システムとエラーハンドリングの改善

  • 算術/ビット演算子のより厳密な型チェック RFC
  • トレイトの抽象メソッドの検証 RFC
  • マジックメソッドのシグネチャ RFC
  • エンジンの警告を整理 RFC
  • 互換性のないメソッドシグネチャは fatal error に。 RFC
  • @ 演算子は、致命的なエラーを隠さなくなりました。
  • private メソッドの継承時のシグネチャチェック RFC
  • Mixed 型のサポート RFC
  • 戻り値で static 型をサポート RFC
  • 内部関数に型アノテーション Email thread
  • 一部の拡張機能が、リソースからオブジェクトに移行: Curl, Gd, Sockets, OpenSSL, XMLWriter, XML

その他文法の調整や改善

  • 引数やクロージャーのuseリストの最後にカンマがつけられるように RFC RFC
  • catch で例外のキャプチャが不要に RFC
  • 変数の文法の調整 RFC
  • 名前空間の名前を単一のトークンとして扱う RFC
  • Throw は式になりました RFC
  • オブジェクトに対して ::class が使えるように RFC

新しいクラス、インターフェイス、関数

To Top