PHP重鎮の廣川類氏のコラム「PHPの最新状況:PHP 8.1開発スタート(第16回)」を公開しました。

PHP

廣川類

PHP 8.0.2の最新バージョンがリリースされたことを受け、次期マイナーリリースであるPHP 8.1の開発が本格化。8.1ではマイナーな機能強化が予定されており、2021年11月末のリリースを目指している。具体的な新機能としては、配列展開演算子の拡張、8進数リテラル表記、配列のリスト判別関数array_is_list()の導入、$GLOBALS変数の利用制約、そしてenum(列挙型)の使用が予定されている。ただし、現在はまだ変更仕様未確定なため、一部内容が変わる可能性もある。

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で採用される予定の機能の一部について紹介しました.現在,変更仕様は未確定な状態ですので,本稿で紹介した内容の一部が変更される可能性があることに注意してください.

<< PHPの重鎮、廣川類氏のコラム「PHPの最新状況:PHP 8.0リリース間近」(第14回)PHPの重鎮である廣川類氏のコラム第17回「PHPの最新状況:PHP開発用サーバーが攻撃を受ける」が掲載されました。 >>

関連記事

Webサイト運用の課題解決事例100選 プレゼント

Webサイト運用の課題を弊社プロダクトで解決したお客様にインタビュー取材を行い、100の事例を108ページに及ぶ事例集としてまとめました。

・100事例のWebサイト運用の課題と解決手法、解決後の直接、間接的効果がわかる

・情報通信、 IT、金融、メディア、官公庁、学校などの業種ごとに事例を確認できる

・特集では1社の事例を3ページに渡り背景からシステム構成まで詳解