# PHP 8 リリース新機能と変更

php 8 は 2020 年 11 月 26 日にリリースされました!🎉
誕生してから 25 年に迎えた PHP が時代とともに進化していて未だに現役で活躍しています。速度倍以上にアップした 2015 年に PHP7 リリースから 5 年、PHP8 が更に速い実行速度でやって来ました。
PHP7 も速いですが、PHP8 になって長時間実行するプログラムは更に1.5 ~ 2 倍の処理速度向上します。

# JIT 実行時コンパイラ

JIT コンパイラー とは

Just In Time Compiler 翻訳すると実行時コンパイラといいます。AOT(Ahead-Of-Time)事前コンパイラとは違ってプログラムが実行されるその時に CPU の機械語に変換(コンパイル)することが JIT です。

さらにさらに、従来よく使うプログラムをメモリにキャッシュしたことをコンパイル済みの機械語をキャッシュするようになり、今回 PHP8 の速度が大幅に改善された原因だそうです。

実際の体感はいろいろでしょうが、1 分かかる処理が 8 秒に完了するとかの話がありました。ワクワクしますね!

# 名前付き引数

名前付き引数 Named arguments (opens new window)

これまで引数の順番を知らないと配列操作できなかったが、json 感覚に引数定義できるようになりました。

// php8新機能
array_fill(start_index: 0, num: 100, value: 50);

// php7
htmlspecialchars($string, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);
// php8
htmlspecialchars($string, double_encode: false);

# アトリビュート

アトリビュート Attributes (opens new window)

アトリビュートは、doc-block コメントと同様に、それらが属する宣言の前に追加されます。それらは、宣言を文書化する doc-block コメントの前または後に宣言できます。

// php8新機能
<< WithoutArgument >>
<< SingleArgument (0>>
<< FewArguments ('Hello''World'>>
function foo(){ }

// php7
class php7PostsController
{
    /**
     * @Route("/api/posts/{id}", methods={"GET"})
     */
    public function get($id) { /* ... */ }
}

// php8
class php8PostsController
{
    #[Route("/api/posts/{id}", methods: ["GET"])]
    public function get($id) { /* ... */ }
}

# コンストラクタ プロパティ

コンストラクタ プロパティ Constructor property promotion (opens new window)

これまでプロパティ宣言して代入する作業の二回定義する必要なものを一回に簡略。

// php7
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;
  }
}

//php8
class Point {
  public function __construct(
    public float $x = 0.0,
    public float $y = 0.0,
    public float $z = 0.0,
  ) {}
}

# ユニオン タイプ

ユニオン タイプ Union types (opens new window)
PHP の特徴でもある複数の型を受け取る、返すことを定義制約できるようになります。



















 





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

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

new Number('NaN'); // Ok

// php8
class Number {
  public function __construct(
    private int|float $number
  ) {}
}

new Number('NaN'); // TypeError

# マッチ式

マッチ式 Match expression (opens new window)
これまでのswitchが使いにくかったが、match使うと簡潔でセキュリティもよくなりました。
matchswitchよりソースコードが短くなるだけではなく、型チェックもやってくれるので、より厳密になります。

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

// php8
echo match (8.0) {
  '8.0' => "Oh no!",
  8.0 => "This is what I expected",
};
//> This is what I expected

// 新機能
echo match ($x) {
    1, 2 => 'Same for 1 and 2',
    3, 4 => 'Same for 3 and 4',
};

# ヌル安全オペレータ

ヌル安全オペレータ Nullsafe operator (opens new window)
これまでnullチェックするためのソースが確かに長過ぎるから、PHP8 では改善されました。javascript のように一行で null チェックができるのがかっこいい!

















 




// php7
$country =  null;

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

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

    if ($address !== null) {
      $country = $address->country;
    }
  }
}

// php8
$country = $session?->user?->getAddress()?->country;

// bar()、baz()は実行されない
null?->foo(bar())->baz();

# 文字と数値比較

文字と数値比較 Saner string to number comparisons (opens new window)
文字列と数値を比較する場合、これまでは文字列を数値に変換してから比較していましたが、今後はより厳密に数値を文字列に変換してから比較するようになります。





 

// php7
0 == 'foobar' // true

// php8
0 == 'foobar' // false

厳密と非厳密比較の違い

文字列と数値を比較する場合 php8 は数値を文字列に変換してから比較
非厳密な比較== != > >= < <= <=>はこの変更で影響されます!

比較項目 厳密な比較 非厳密な比較
文字列 文字列をセマンティクスと比較 文字列が数値の場合は数値として扱う「スマート」比較
配列 キーが同じ順序必要 キーが同じ順序必要ない
オブジェクト オブジェクト ID で比較 オブジェクトのを比較
比較 PHP7 PHP8
0 == "0" true true
0 == "0.0" true true
42 == "42" true true
0 == "foo" true false
0 == "" true false
42 == "42foo" true false
"0" == "0" true true
"0" == "0.0" true true
"0" == "foo" false false
"0" == "" false false
"42" == "42" true true
"42" == "42foo" false false
var_dump((int)"foo");   // int(0)
var_dump((int)""   );   // int(0)
var_dump((int)"42foo"); // int(42)
2020-12-01
  • php

関連記事

正規表現一覧 よく使う検索・置換のパターン
Apache 初期設定メモ
Elastic Beanstalk \$\SERVER['REMOTEADDR'] 取得できない
codeigniter email ライブラリでメール送信 日本語対応
php 開発におけるコーディングルール・規約
PHP empty isset is_null の違い
php curl 使って クリックなしで POST 送信
FlattenException deprecated
allowurlinclude の設定で ftp_connect()エラー
Lumen と Laravel 違い比較
Laravel 5.7 の MVC 使う時のメモ
解決!phpMyAdmin テーブル構造の内容が表示されない問題
Smarty HTTP URL 取得できるサーバー関数
twig 3 人気 PHP テンプレートエンジンがバージョンアップ
開発時によく使うゼロ埋めパディング作業まとめ
nuxtjs と codeigniter で jwt システム構築
HTML から PDF に変換 PHP ライブラリ mPDF の設定
PHP 7.4 にアップグレードして使えなくなる機能
php.ini 初期設定のいろいろ
爆速軽量フレームワーク codeigniter PHP 開発
Composer コマンドとオプション
Laravel Error についてのメモ