こんにちは、すっかり秋も深まり、PHP 7.2のリリースもいよいよ近づいてきました。今回は前回に続き、11月にリリースされる予定のPHP 7.2に関する情報を紹介します。
PHPのバージョンとリリース時期
PHPでは、5年でメジャーバージョンアップが行われています。具体的には、PHP 4.0は2000年、PHP 5.0は2004年、PHP 7.0は2015年にリリースされています。PHP 5.0からPHP 7.0の間にPHP 6.0がリリースされていないのを不思議に思った方がいるかもしれません。実は、PHP 6.0は2010年頃にリリースされるべく開発されていましたが、内部データをUnicodeに完全対応させるために開発規模が大きくなりすぎ、キャンセルされています。PHP 5.0のリリースからPHP 7.0のリリースまでに11年もかかっているのはそのためです。
バージョンの2桁目が上がるマイナーバージョンアップ(7.1、7.2、など)は、概ね年1回行われます。マイナーバージョンアップでは、通常、言語上の大きな仕様変更は行われませんが、機能の追加が行われることがあります。なお、PHP 6.0用に準備されていた機能の多くは、PHP 5.3およびPHP 5.4に取り入れられました。このため、名前空間やラムダ関数等、PHP 5.3にはメジャーバージョンアップといっても良いくらいの大きな言語上の仕様追加が行われています。
バージョンの3桁目が上がるマイナーバージョンアップ(7.1.1、7.1.2、など)は、バグ修正を目的としたリリースで、概ね月1回行われます。
PHPのサポート期間
PHPでは、特定のバージョンがリリースされた後、バグの修正を目的年経リリースが行われます。一方、PHPはオープンソースソフトウエアとして無償で配布されており、開発者の多くはボランティアとして開発に参画しているため、開発・サポートに関するリソースには制約があります。PHPでは、こうした制約を考慮して、バージョンの2桁目が上がるマイナーバージョンアップの標準ライフサイクルを3年と定めています。このうち、最初の2年では通常のバグ修正が行われ、最後の1年ではセキュリティに関係する修正のみが行われます。ユーザは、この期間に次のバージョンに更新する必要があります。図1に現在主に使われているPHPのバージョンのサポート期間を示します。ここで、EOL(、End-of-Life)は、サポート期間が完全に終わるタイミングを意味します。EOLを過ぎたバージョンでは、セキュリティに関する修正についても実施されなくなります。ただし、例えば、Linuxのディストリビューションによっては、独自のサポートが継続され、バグ修正が継続的に行われるケースもあります。
PHP 5でサポート中なのはPHP 5.6のみで、例えば、PHP 5.5のEOLは2016年7月と1年以上も前です。PHP 5.6よりも前のバージョンを使用している場合は、セキュリティ上のリスクが高いため、早期のバージョン更新をお勧めします。なお、2014年8月にリリースされたPHP 5.6のライフサイクルは、本来、2017年8月で終了するはずでしたが、PHP 5を使うユーザがまだ相当数残っていることを考慮し、2018年末まで延長されています。この間にPHP 7にバージョン更新することをお勧めします。
図1 PHP各バージョンのサポート期間
W3Techs.comの統計によれば、PHP 5のユーザはPHPユーザ全体の94%を占めており、サポート期間が切れているPHP 5.5以前のユーザも63%もいる状態となっています。セキュリティに関する攻撃手法も年々進歩しており、バグ修正期間が終了している状態のシステムを運用することは非常に危険な状態と言えます。繰り返しとなりますが、早期のバージョン更新を強くお勧めします。
PHP 7.2における変更点
それでは、いよいよPHP 7.2における変更点について順番に説明します。主な変更点は以下となります。
(1)クラス型宣言におけるobjectキーワードの導入
(2)レガシー機能の廃止
(3)高度な暗号機能の標準サポート
PHPでは、クラスメソッドや関数の引数で型宣言(タイプヒンティング)を行うことで、型チェックを行うことができます。従来のバージョンでは、引数にオブジェクト(クラスのインスタンス)を指定する場合、当該クラス名または基底クラスの名前を指定する必要がありました。
PHP 7.2では、クラスに関する型宣言で汎用のオブジェクトを意味するキーワードobjectが使用できるようになりました。これにより、単にオブジェクトが指定されたかどうかを確認したい場合にも型宣言が使用できるようになりました。例として以下のコードを見てみましょう。
<?php
class Foo {public $name=’Taro’;}
class Moo {public $name=’Hanako’;}
$obj1 = new Foo;
$obj2 = new Moo;
function test(object $arg) {
return $arg->name;
}
echo test($obj1); // Taro
echo test($obj2); // Hanako
ここでは、2つのクラス(FooおよびMoo)を別々に定義し、それぞれのインスタンス($obj1および$obj2)を作成して関数testに指定しています。ここで、オブジェクトかどうかを引数で確認するために型宣言にobjectを指定しています。
同様に、メソッドまたは関数の戻り値の宣言にも汎用のオブジェクトを表すobjectキーワードが使用できるようになりました。サンプルコードを以下に示します。
function foo() : object {
$obj = json_decode(‘{}’);
return $obj;
}
レガシー機能の廃止
PHP 7.2では、PHP 7.1で廃止予定とされていた暗号に関するエクステンションmcryptが標準アーカイブから削除され、PHPエクステンション用レポジトリPECL (PHP Extension Community Library)に移動されました。
また、表1に示すいくつかの機能が新たに廃止対象となっています。これらの機能は、次のメジャーバーションであるPHP 8.0以降で廃止される予定です。
mbstring.func_overloadは、PHP 4で導入された機能で、strlenなどのシングルバイト文字にのみ対応する関数をmbstrlenなどのマルチバイト文字に対応する関数に実行時に置き換えることができます。この機能は、シングルバイト文字のみに対応するアプリケーションをマルチバイト文字に対応させる際の作業を容易にするために用意されたもので、移植を完了するまでの間、テンポラリに使用されることが想定されていました。しかし、この機能は、長期にわたり使用され続け、誤った使用方法によりサービス停止攻撃(DoS)を受けるなどのセキュリティ上の問題を引き起こす可能性が指摘されてきました。現時点では、Unicodeの普及によりマルチバイト文字に対応することが一般的になっており、この機能の有用性はなくなったと考えられます。
第二引数なしのparse_str()は、セキュリティ上の理由により廃止されます。parse_str()関数に第一引数のみを指定すると、第一引数に指定した文字列がパースされ、グローバル空間に変数が定義されます。結果として、コード内の変数が外部入力で上書きされるリスクが生じ、セキュリティ上の脆弱性を生み出す要因となります。
その他の機能(create_functionなど)は、より優れた代替機能がサポートされたために廃止される予定となっています。
表1 PHP 7.2で廃止対象とされた機能
廃止対象 | 代替 |
__autoload | spl_autoload_register() |
$php_errormsg | error_get_last()またはerror_clear_last() |
create_function() | クロージャ(PHP 5.3以降) |
mbstring.func_overload | – |
第二引数なしのparse_str() | – |
each() | foreach() |
次回は、いよいよPHP 7.2の追加機能の目玉であるセキュリティ関連の機能について紹介します。