はじめに
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
型にtrue
とfalse
の値があるようなイメージです。
下記で説明されています。
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 セレクトボックスの値として使用する
セレクトボックスの値として使用するまでに以下の手順でコードを書いていきます。
- caseにラベリングする
- 全てのcaseを配列で取得する
- 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
関数がクラスのインスタンスを返します。
そのインスタンスが複数のインタフェースA
、B
を継承しているかを交差型でチェックしています。
<?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. 参考