0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

PHP8.1の新機能を試してみた

Posted at

はじめに

PHP8.1の新機能を試してみました。
試した機能は以下です。

  • 文字列をキーとして持つ配列のアンパック
  • 列挙型
  • 交差型

それではそれぞれの詳細と具体例を書いていきたいと思います。

1. 文字列をキーとして持つ配列のアンパック

文字列のキーを持つ配列を展開できるようになりました。

<?php
$arr1 = ['foo' => 'foo'];
$arr2 = [...$arr1, 'bar' => 'bar'];
var_dump($arr2);
// 実行結果
array(2) {
  ["foo"]=>
  string(3) "foo"
  ["bar"]=>
  string(3) "bar"
}

この機能のおかげで連想配列が扱いやすくなりそうです。

2. 列挙型

列挙型は独自の型を定義するための機能で、セレクトボックスで設定する値に使用したり、バリデーションに使えるかと思います。

ここでは定義方法からセレクトボックスの値として使用する方法まで具体例を書きたいと思います。

2.1 定義する

下記では会員ランクの型を定義しています。

<?php
enum MembersRank
{
    case Regular;
    case Silver;
    case Gold;
    case Platinum;
}

function foo(MembersRank $members_rank)
{
	return $members_rank;
}

var_dump(foo(MembersRank::Platinum));
// 出力
enum(MembersRank::Platinum)

上記のコードはMembersRank型を定義し、その型の値が4つ設定されているような状態です。
boolean型にtruefalseの値があるようなイメージです。

下記で説明されています。

MembersRank型の有効な値は以下の4つになります。

  • MembersRank::Regular
  • MembersRank::Silver
  • MembersRank::Gold
  • MembersRank::Platinum

上記以外は許容しませんので下記のようにfooの引数に文字列を渡すとMembersRank型にしなさいと怒られてしまいます。

<?php
enum MembersRank
{
    case Regular;
    case Silver;
    case Gold;
    case Platinum;
}

function foo(MembersRank $members_rank)
{
	return $members_rank;
}

var_dump(foo('bar'));
// エラー
Fatal error: Uncaught TypeError: foo(): Argument #1 ($members_rank) must be of type MembersRank, string given, called in /home/user/scripts/code.php on line 14 and defined in /home/user/scripts/code.php:10

今のところどう使えばいいか想像がつきにくいと思いますが、
例を見ていくと徐々にわかってくるのでご安心ください。

2.2 セレクトボックスの値として使用する

セレクトボックスの値として使用するまでに以下の手順でコードを書いていきます。

  1. caseにラベリングする
  2. 全てのcaseを配列で取得する
  3. casesを利用して設定した文字列を全て取得する

2.2.1 caseにラベリングする

それぞれのcaseに対して、整数や文字列で値を設定することができます。
下記では文字列を設定しています。

<?php
enum MembersRank: string // 型を宣言する
{
	case Regular = 'レギュラー';
    case Silver = 'シルバー';
    case Gold = 'ゴールド';
    case Platinum = 'プラチナ';
    
    function get_members_rank()
	{
		return $this->value;// 定義した値を取得
	}
}

function foo(MembersRank $members_rank)
{
	return "あなたは{$members_rank->get_members_rank()}メンバーです。";
}

$value = "Platinum";
echo foo(constant("MembersRank::{$value}"));
// 出力
あなたはプラチナメンバーです。

$this->valueで設定した値を取得することができます。
ちなみに値を設定した場合は型を宣言しないとエラーになってしまうでお忘れなく。

2.2.2 全てのcaseを配列として取得する

casesメソッドを使用すると全てのcaseを配列として取得することができます。
casesは列挙型に対してあらかじめ定義されています。

<?php
enum MembersRank: string
{
    case Regular = 'レギュラー';
    case Silver = 'シルバー';
    case Gold = 'ゴールド';
    case Platinum = 'プラチナ';
}

var_dump(MembersRank::cases());
// 出力
array(4) {
  [0]=>
  enum(MembersRank::Regular)
  [1]=>
  enum(MembersRank::Silver)
  [2]=>
  enum(MembersRank::Gold)
  [3]=>
  enum(MembersRank::Platinum)
}

2.2.3 casesを利用して設定した文字列の値を全て取得する

casesで取得した配列をforeachで回して値を配列に格納していきます。

<?php
enum MembersRank: string
{
    case Regular = 'レギュラー';
    case Silver = 'シルバー';
    case Gold = 'ゴールド';
    case Platinum = 'プラチナ';

	static public function get_label_list()
	{
		$list = [];
		foreach(MembersRank::cases() as $case) {
			array_push($list, $case->value);
		}
		return $list;
	}
}

var_dump(MembersRank::get_label_list());
// 出力
array(4) {
  [0]=>
  string(15) "レギュラー"
  [1]=>
  string(12) "シルバー"
  [2]=>
  string(12) "ゴールド"
  [3]=>
  string(12) "プラチナ"
}

上記のように取得した値をセレクトボックスで使用することができます。
列挙型を使用するとあらかじめ値を限定した状態にできるため不正な値が入りづらくなります。

3. 交差型

下記の記事を参考にさせていただきました。

交差型はクラス型、インターフェース型を、アンド条件で型宣言できる機能です。
A&Bと宣言すると、AとBを満たした場合のみ許容するようになります。

以下の例ではget_class_inherits_AB関数がクラスのインスタンスを返します。
そのインスタンスが複数のインタフェースABを継承しているかを交差型でチェックしています。

<?php
interface A
{
	public function A();
}

interface B
{
	public function B();
}

class foo implements A, B
{
	public function A() {
		return 'A';
	}
	
	public function B() {
		return 'B';
	}
}

function get_class_inherits_AB($type): A&B { // 交差型で宣言
	if ($type === 'foo') {
		return new foo();
	}
}

function bar($foo) {
	return $foo->A() . "\n" . $foo->B();
}

echo bar(get_class_inherits_AB('foo'));

主にクラスにインタフェースが継承されているかのチェックに使用できそうです。

4. おわりに

ここまで読んでいただきありがとうございました。
試した機能の数は少なかったですが、どれもガンガン使っていけそうな便利な機能でした。

5. 参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?