今回のコラムでは,今年3月末に話題となったPHP開発用サーバーが攻撃を受けた件の経緯と対策状況について紹介します.一方,今年末にリリースが予定されるPHP 8.1の開発がいよいよ本格化しています.今回は前回に続いて,PHP 8.1に採用される予定の新機能として列挙型について紹介します.
PHPソースコードへの不正なコミットと対応状況
2021年3月28日,PHPのオリジナル原作者であるRasmus Lerdorf氏と主要な開発者であるNikita Popov氏の名前でPHPの開発用ソースコードに対して不正なコミットが行われました.このコミットは,特殊な文字列がHTTPヘッダの中に含まれている場合にそのuseragent HTTPヘッダに含まれるPHPコードをリモート実行するリモートコード実行(RCE)の脆弱性をPHPに発生させる危険なものでした.このコミットは,PHP開発者によりただちに検出・排除され事なきを得ました.また,今回の不正なコミットは,リリース前の開発用のソースコードに行われた変更であり,一般に使用されるPHPのリリース版のソースコードには影響を与えていません.
この攻撃では,開発者のユーザデータベースが漏洩したことが原因と考えられており,対策として開発用サーバーをより強固なセキュリティ機構を有するGithubに移行させると共に,全ての開発者のパスワードがリセットされました.Githubは従来ミラーサーバーとして活用されていましたが,今後は直接のコミット先となります.管理者のアカウント管理システムも実装もやや古いコードが残っていたため,この機会に刷新されています.また,PHPのレポジトリにコミットを行う開発者は2段階認証を有効とすることが必須となっています.
PHP 8.1の開発情報
PHP 8.1は今年末のリリースに向けて順調に開発が進んでいます.4月中に選挙によりリリースマネージャが決定される予定です.現時点の計画では,6月にアルファ版,7月にフィーチャーフリーズをリリースした後,ベータ版を7~8月にリリース,リリース候補版を9~11月にリリースした後,11月25日に正式版(PHP 8.1.0)がリリースされる予定です.7月のフィーチャーフリーズに向けて,新機能の提案が複数行われており,今後,投票により採用が決まる予定です.
以下,実装が完了した主要機能として列挙型を紹介します.
列挙型(Enum)の導入
PHP 8.1では,列挙型が導入されます.導入される列挙型はクラスとして実装されており,caseの後に各選択子を記述します.
enum Status {
case ALPHA;
case BETA;
case RELEASE;
}
以下に簡単な使用例を示します.
class ReleaseManager {
public function getStatus(Status $status) {
return $status->name;
}
}
$status=Status::BETA;
$obj=new ReleaseManager();
print $obj->getStatus($status); // 出力:BETA
この例では,$status変数に列挙型Status::BETAを代入し,クラスReleaseManagerのメソッドgetStatusの引数として指定しています.getStatusは列挙型であるStatusを引数とします.列挙型ではプロパティ変数nameが定義されており,当該変数の名前(この例ではBETA)を取得できます.
列挙型はクラスとして実装されているため,以下のようにメソッド(またはインターフェイス)を実装することができます.以下の例を見てみましょう.
enum Status {
case ALPHA;
case BETA;
case RELEASE;
public function info(): string
{
return match($this) {
self::ALPHA => ‘Alpha Release’,
self::BETA => ‘Beta Release’,
self::RELEASE=>’Public Release’,
};
}
}
この例では,メソッドinfoを導入しています.infoメソッドの使用例を以下に示します.
$status=Status::BETA;
print $status->info(); // 出力:Beta Release
メソッドの中では,selfやstaticなどのキーワードが使用できます.ここでは,match式により各列挙型変数の値に対応するメッセージを返しており,この例の出力は “Beta Releas” となります.
列挙型では,整数(int)または文字列(string)の値を対応させることができます.以下に文字列を指定する場合の例を示します.
enum Status : string {
case ALPHA = “Alpha Release”;
case BETA = “Beta Release”;
case RELEASE = “Public Release”;
}
この値は,プロパティ変数valueにより取得できます.以下に例を示します.
$status=Status::BETA;
print $status->value; // 出力:Beta Release
この例では,文字列に対応する列挙型変数において,BETAに対応する文字列”Beta Release”が出力されます.
列挙型では,cases()により全ての変数を配列として取得できます.
上記の列挙型の使用例を以下に示します.
foreach (Status::cases() as $status) {
printf(“%s => %d\n”,$status->name,$status->value);
}
出力は以下のようになり,各変数に対応する値が出力されます.
ALPHA => 1
BETA => 2
RELEASE => 3
列挙型はデータの記述性を向上させることができ,PHPでも実装が望まれていた機能です.次回以降も順次PHP 8.1の新機能を紹介していく予定です.