#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で比較オブジェクトのを比較
比較PHP7PHP8
0 == "0"truetrue
0 == "0.0"truetrue
42 == "42"truetrue
0 == "foo"truefalse
0 == ""truefalse
42 == "42foo"truefalse
"0" == "0"truetrue
"0" == "0.0"truetrue
"0" == "foo"falsefalse
"0" == ""falsefalse
"42" == "42"truetrue
"42" == "42foo"falsefalse
var_dump((int)"foo");   // int(0)
var_dump((int)""   );   // int(0)
var_dump((int)"42foo"); // int(42)
2020-12-01
  • php

関連記事

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