🐘

[PHP]PHP7からPHP8.0.xの新機能アップデートを今更まとめる

2023/10/18に公開

結論

いきなりの結論ですが、アップデートに関してはPHP公式を確認したら全てまとまってます

https://www.php.net/manual/ja/migration80.php

ここでは上記ページを確認した結果をまとめることにします

新機能

https://www.php.net/manual/ja/migration80.new-features.php

PHP Core

名前付き引数

https://www.php.net/manual/ja/functions.arguments.php#functions.named-arguments

概要

  • 関数の引数に名前を付け呼び出し側では名前指定の引数を渡せるようになった
  • 引数は順番が大事だったが名前付き引数によって順番関係なく引数を渡せるようになった

<?php
function calcTriangle($bottom, $height): float
{
    return ($bottom * $height) / 2;
}
// 引数名を指定して関数を呼び出す
echo calcTriangle(bottom: 10, height: 5);
// 順番が前後してもOK
echo calcTriangle(height: 5, bottom: 10);

所感

  • 見た目上どの引数に何が渡ってるか見れるのは可読性上がって良いんじゃないか
  • コードが長くなるのでコーディング規約で決めておかないとごちゃ混ぜは見にくくなりそう

アトリビュート

https://www.php.net/manual/ja/language.attributes.php

概要

  • コンピュータが解析可能な構造かされたメタデータ情報をコード宣言時に埋め込める
  • ??????
  • パッと見は「アノテーション」のような感じらしい
  • 実用性を理解するのに時間がかかりそうな機能
  • 従来のPHPDocで書かれていたものを代替しようとするもの、らしい

参考サイト様

PHP 8 で導入される Attributes 事始め
Attributesで実現するPHP8時代のバリデータ
PHP8で面倒な Getter 定義から卒業しよう

※理解が追いつかないので具体例は差し控えようと思いますw

所感

  • バリデーションをアトリビュートで定義することもできるらしい
  • より厳格な定義を技術したアトリビュートを利用して処理を記述できる

コンストラクタのプロモーション

https://www.php.net/manual/ja/language.oop5.decon.php#language.oop5.decon.constructor.promotion

概要

  • コンストラクタの引数をクラスプロパティに昇格さえることができる
  • 従来のコンストラクタの短縮記法となる

新記法
<?PHP
class Point
{
	public function __construct(protected int $x, protected int $y = 0){}
}
従来記法
<?php
class Point
{
    protected int $x;
    protected int $y = 0;

    public function __construct(int $x, int $y = 0)
    {
        $this->x = $x;
        $this->y = $y;
    }
}

所感

  • コンストラクタをかなり省略できるので使い所
  • ただSetするだけにタイピングするのはかなり面倒くさかったので助かる

union 型

https://www.php.net/manual/ja/language.types.declarations.php#language.types.declarations.composite.union

概要

  • 複数の型指定が可能になった

参考サイト様

<?php
public function fooBar(int|float $value): int|float
{
	return $value;
}

所感

  • 厳密さが下がるのであまり使わない気がするけどどうなんだろ?

match式

https://www.php.net/manual/ja/control-structures.match.php

概要

  • 分岐チェック式
  • Switch式と似ているが比較が厳密(===)なものになっている
  • 値を返す
  • 一致したものがあった時点で値を返して終了する
  • 必ず分岐のいずれかに一致が必要で一致しない場合 UnhandleMatchError がスローされる
  • 一致しない場合に返す default を使用可能

<?php
$val = 'apple';

$fruit = match ($val) {
    'apple', 'orange' => 'apple or orange',
    'banana' => 'banana',
    default => 'other',
};
var_dump($fruit); // apple or orange

所感

  • これは嬉しいアップデート
  • 厳密チェックしてくれる分岐式は待望の機能ではなかろうか

nullsafe 演算子

https://www.php.net/manual/ja/language.oop5.basic.php#language.oop5.basic.nullsafe

概要

  • プロパティやメソッドに ?-> を使用してアクセスする
  • アクセスしたプロパティやメソッドが存在しない場合に例外スローではなく null が返される
  • null となったった時点で後続にチェインした処理があってもスキップされる
  • null チェックを減らすことが可能になる

<?php
// PHP 8.0.0 以降は、このように書けます:
$result = $repository?->getUser(5)?->name;

// これは、以下のコードチェックと同等です:
if (is_null($repository)) {
    $result = null;
} else {
    $user = $repository->getUser(5);
    if (is_null($user)) {
        $result = null;
    } else {
        $result = $user->name;
    }
}

所感

  • これも最高の機能の1つですね
  • 存在チェクをかなり短く書ける待望の機能でしょう

その他の新機能

WeakMapクラス

https://www.php.net/manual/ja/class.weakmap.php

  • オブジェクトをキーとして受け入れるマップ(辞書)

ValueErrorクラス

https://www.php.net/manual/ja/class.valueerror.php

  • ValueErrorは引数の型は正しいが値が正しくない場合にスローされる

任意の数の関数の引数を可変長引数に置き換えられるようになった

<?php
class A {
     public function method(int $many, string $parameters, $here) {}
}
class B extends A {
     public function method(...$everything) {}
}

static ("遅延静的束縛"における) 型を戻り値の型として使えるようになった

<?php
class Test {
     public function create(): static {
          return new static();
     }
}

オブジェクトのクラス名を $object::class で取得できるようになった

  • 従来は get_class($object)

new と instanceof の新機能

  • 任意の式をそれぞれで利用可能になった
  • new (expression)(...$args) や $obj instanceof (expression) という形で、任意の式と一緒に使えるようになりました。

Trait の新機能

  • private な抽象メソッドを定義できるようになった
  • 抽象メソッドはトレイトを使うクラスで実装しないといけない

Throwが式として利用可能に

  • Throwの新しい書き方
<?php
$fn = fn() => throw new Exception('Exception in arrow function');
$user = $session->user ?? throw new Exception('Must have user');

引数最後にカンマ許可

<?php
function functionWithLongSignature(
    Type1 $parameter1,
    Type2 $parameter2, // <-- このカンマが許可されるようになりました
) {
}

catch() で変数無しでもよくなった

  • try catch の catch で変数無しにしても良くなった
<?php
try{
    new PDO();
}catch(\Throwable){
    echo "なんかエラー出た";
}

mixed型

  • mixed型が利用可能になった
<?php
function foo(mixed $arg){}
foo(1);
foo('x');
foo(new stdClass());
株式会社THIRD エンジニアブログ

Discussion