PHPの最新状況:PHP 8.5もうすぐリリースへ (第45回) 

PHP

廣川類

11月に入り,徐々に気温が下がる日が続いています.前回の記事から少し間が空きましたが,引き続きPHPの次のマイナーバージョンであるPHP 8.5の開発は順調に進捗しており,11月20日の正式公開が間近に迫っています.本連載では,前回に引き続きPHP 8.5で強化される機能について紹介していきます. 

PHP設定ファイルの変更確認 

PHPでは,実行時のオプションを設定ファイル(標準でphp.ini)で指定します.PHPの設定では,各オプションのデフォルト値が内部的に定義されており,php.iniにおいて各オプションの値が設定されると,その値が使用されます.通常は,デフォルト値を使用することで,PHP開発者が意図した動作となりますが,標準の動作を変更する必要がある場合に,オプションを指定して動作を変更します. 

これらのオプションの種類は,PHP本体と各エクステンション用を合わせると極めて数が多く,管理も大変です.PHPには,開発環境用のphp.ini-development,運用環境用のphp.ini-productionの2種類の設定ファイルのサンプルが付属していますが,コメントを含む総行数は1800行以上にもなります.設定ファイルの記述に誤りがあると,意図した動作にならないばかりか,セキュリティホールを発生する要因にもなります.  

PHPでは,従来から,phpinfo()の出力などにより,オプションの設定状況を知ることができました.PHP 8.5では,デフォルト値から変更されているオプションのみを抽出して表示することができるようになりました. 

具体的には,PHPインタプリタの実行時オプションとして,–ini=diff を指定します. 

$> php –ini=diff 

出力は,例えば,以下のようになります. 

Non-default INI settings: 

allow_url_include: "0" -> "" 

auto_append_file: (none) -> "" 

auto_prepend_file: (none) -> "" 

… (中略) 

zlib.output_compression: "0" -> ""

デフォルト値から変更されているオプションを表示することで,オプション設定の確認を効率化できます. 

定数式におけるクロージュおよびFCCのサポート 

PHPでは,引数に応じて静的な値を設定する定数式を利用することができます.しかし,PHP 8.5より前のバージョンではクロージャに対応していなかったため,関数の引数をコールバック関数により指定するといったことはできませんでした. 

PHP 8.5より前のバージョンのコードの例として以下を見てみましょう.my_array_filter関数において,配列を第一引数,コールバック関数を第二引数に指定し,配列の各要素が空でないものを配列として返します.この関数では,コールバック関数を定数式として指定できないため,仮にnull値を指定し,関数の先頭行で引数がnullの場合に,empty関数を用いた定数式をstaticクロージャとして指定しています. 

以下のようなコマンドを実行すると,配列 [1, “foo”] が出力されます. 

var_dump(my_array_filter([0, 1, ”, ‘foo’]));  

empty関数では,0 や空文字列 ” は空として判定されます. 

PHP 8.5では,定数式でクロージャが指定できるようになりました.これにより,関数の任意の引数に引数に応じた値をスタティック関数の戻り値として指定することができるようになります. 

先ほどの例は,PHP 8.5以降では関数の引数に直接staticコールバック関数を記述することで,以下のようによりシンプルに記述することができます. 

また,PHP では,PHP 8.1以降,FCC (First Class Callables) というcallableからクロージャ(無名関数)を生成する簡易的な記法がサポートされています.上記の定数式におけるクロージャのサポート追加に関連して,PHP 8.5では,定数式においてFCCがサポートされます. 

具体的には,以下のようにFCC構文によりcallable(strrev関数)からクロージャを生成します. 

例えば、以下のように定数式をコールすることができます。

出力は,”dbca” となります. 

RFC3986, WHATWG URLに対応したAPI 

PHPでは,parse_url()のような複数の関数でURLのパースを行うことができます, URLの記法には,RFC 3986,WHATWG URLなどの標準が存在しますが,従来のPHPは概ね標準と同じ動作をするものの,これらの標準に準拠しているわけではありませんでした.このため,PHPがサポートするfilterエクステンションによりURLに関するフィルタ処理を行った後,RFC3986に準拠するcURLエクステンションでコンテンツ取得を行うと,URLに関する処理の不整合により,セキュリティ上の問題などを発生するリスクがあります. 

 PHP 8.5では,RFC 3986やWHATWG URLに基づきURLのパースを行うAPIが追加され,Webブラウザ等がサポートする標準的なURL処理の仕組みが利用できるようになります. 

 RFC3986は,2005年に提案されたURI (Uniform Resource Identifier)に関する標準です.RFC3986では,URIのサブセットとして,URL (Uniform Resource Locator)が定義されています. 

 RFC3986に基づきURIの処理を行う際には,名前空間Uri\RFC3986にあるUriクラスのオブジェクトのインスタンスを生成します.引数に,URIを指定します. 

出力は,以下のような連想配列となり,指定したURIがパースされて要素毎に分解されていることがわかります. 

[scheme: “https”,  
username: “username”,  
password: “password”,  
host: “example.com”,  
port: 8080,  
path: “/path” 
query: “q=r” 
fragment: “fragment”] 

一方,WHATWGにより2012に開始されたURL Standardでは,URL自体の仕様を定義しており,RFC 3986に代わる標準となることを目標としています. WHATWG URLに基づきURIの処理を行う際には,名前空間Uri\WhatWgにあるUrlクラスのオブジェクトのインスタンスを生成します.引数に,URLを指定します. 

 この場合の出力は,上記のRFC3986に関する例と同じになります.URLオブジェクトでは,各種のメソッドが定義されています.ホスト名を取得するには,getAsciiHostメソッドまたはgetUnicodeHostメソッドを用います.後者では, URLがUnicodeで記述されているものとして処理が行われます.出力はいずれも “example.com” となります. 

入力のURLを取得するには,toAsciiStringメソッドまたはtoUnicodeStringメソッドを利用します.後者はUnicodeを文字セットとして扱うことができます. 

出力はいずれも以下となります. 

“https://username:password@example.com:8080/path?q=r#fragment” 

 不正なURLを指定した場合は例外InvalidUrlExceptionが発生します.UrlクラスのstaticメソッドparseによりURLオブジェクトのインスタンスを生成することも可能です. 

parseメソッドの第3引数に配列を指定すると,その配列にエラーの内容が記録されます. 

不正なURLの場合,$urlの値はNULLとなり,配列errorsに以下のようなエラーの内容が取得されます. 

context =>”invalid  url” 
type => enum(Uri\WhatWg\UrlValidationErrorType::MissingSchemeNonRelativeUrl) 
failure => true 

今回は、次期マイナーバージョンであるPHP 8.5に関する情報として変更点および追加される機能のいくつかを紹介しました.次回までにPHP 8.5の正式リリースが行われるはずです.PHP 8.5の新しい機能をぜひ体験していただければと思います. 

関連記事

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

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

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

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

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