2020年11月26日に5年ぶりのメジャーバージョンアップとしてPHP 8.0.0がリリースされ,早くも3か月がたとうとしています.PHP 8.0のバグ修正版が従来と同様に月一回のペースでリリースされており,本稿執筆時点で最新のバージョンは2021年2月4日にリリースされたPHP 8.0.2となっています.一方,次期マイナーリリースにあたる PHP 8.1の開発も本格的に開始されています.PHP 8.1においては比較的マイナーな機能強化が行われると想定されており,開発が順調に行けば今年(2021年)の11月末頃にリリースされる予定です.PHP 8.1における変更点はまだ確定していませんが,本稿では現時点で採用される予定の機能の一部について紹介します.
文字列キーによる配列展開
PHP 7.4においては,配列展開用の演算子(”…”)が追加されました.以下のように配列定義の中でドット3個(”…”)の後に配列変数を記述すると,配列の要素が自動的に展開されます.以下の例では,配列$xの定義において配列$a,$bの要素を展開しています.
$a=[1,2];
$b=[3,4,5];
$x=[0,…$a,…$b,6]; // [0,1,2,3,4,5,6]
この機能は既存の配列の要素を用いて,新たな配列を定義する際に有用ですが,PHP 7.4では数値を添字とする配列のみでしか利用できないという制約がありました.
PHP 8.1ではこの機能が拡張され,文字列を添字とする連想配列についても”…”演算子による展開が可能となります.以下の例では,配列$xの定義において配列$a,$bの要素を展開しています.
$a=[“a”=>1,”b”=>0];
$b=[“b”=>2];
$x=[“a”=>0,…$a,…$b]; // [“a”=>1,”b”=>2]
この際,各添字に複数回値が指定された場合,左から順番に解釈され,最後に指定された値が最終的な値となります.この例では,配列$xを定義する際,添字”a”の値として最初0が代入されますが,配列$aの要素を代入した際に値が1に更新されます.添字”b”の値についても,配列$aを展開した際に0が代入されますが,配列$bを展開した際に2に更新されます.
8進数リテラル表記
従来,0で始まる数値(例えば012)は8進数として解釈されていました.一方,2進数や16進数は0b0110や0x7Fのように表記されます.PHP 8.1では,8進数においても2進数や16進数に類似の表記ができるように機能が拡張されます.具体的には,従来の012(10進数で10)は0o12(または0O12)のように記述できるようになります.従来の012のような8進数表記は時にプログラムが意図せずに8進数と解釈されてしまうなどの混乱を発生する可能性がありましたが,新規に導入される表記では明示的に区別することができます.
array_is_list関数
PHPにおいては,配列として,数値添字のみを有するリストと,文字列を添字とする連想配列を定義することができます.ここで,数値添字の場合でも添字の順番が逆であったり,抜けている場合にはリストとして定義されないことに注意してください.これらの区別はPHPにより自動的に行われますが,プログラマが意図せずにリストが連想配列として定義されることもありました.
PHP 8.1では配列のリストであることを判別する関数array_is_list()が導入されます.例えば,以下のコードを見てみましょう.
—
<?php
$x = [‘b’,’a’];
var_export(array_is_list($x)); // true
$x = [0=>’b’,1=>’a’];
var_export(array_is_list($x)); // true
$x = [1=>’a’,0=>’b’];
var_export(array_is_list($x)); // false
—
1番目は配列の定義時に添字が指定されていないため,自動的に数値添字(0および1)が割りつけられます.2番目の例は数値の添字を明示的に0から順番に指定しています.これらの二つの例では配列はリストとして定義されるため,array_is_list()関数の戻り値はtrueとなります.
一方,3番目の例では,数値添字を逆順に定義しているため,リストとしては作成されず,array_is_list()関数の戻り値はfalseとなります.
$GLOBALS変数に関する利用制約
$GLOBALS変数は,PHP内部のグローバル変数用シンボルテーブルを直接参照する手段として使用することができます.例えば,以下のコードはグローバル変数への通常の代入($a=1)と同じ効果があります.
$GLOBALS[‘a’]=1
グローバル変数はPHPスクリプトの中において容易に参照できるため,この機能を明示的に使用するコードを各機会は少ないと思われますが,過去のコードの中にはこの機能を利用しているものがあります.この$GLOBALS変数に関するアクセスはグローバル変数のシンボルテーブルを参照するため,操作によっては実行性能の低下を招く懸念があります.このため,PHP 8.1では$GLOBALS変数へのアクセスの一部を制限することにしました.具体的には,以下のようなコードを実行するとコンパイル時に致命的なエラーを発生するようになります.
$GLOBALS = [];
$GLOBALS += [];
$GLOBALS =& $x;
$x =& $GLOBALS;
unset($GLOBALS);
enum(列挙型)
PHP 8.1ではenum(列挙型)が使用できるようになります.Enum型の採用は現時点でPHP 8.1における最大のトピックスと思われます.すでに投票で採用が決まっていますが,本稿執筆時点ではPHP本体のgitレポジトリへのマージ作業中であるため,本機能については次回以降で紹介を行います.
今回は,PHP 8.1で採用される予定の機能の一部について紹介しました.現在,変更仕様は未確定な状態ですので,本稿で紹介した内容の一部が変更される可能性があることに注意してください.