PHP 7.2は11月30日に正式にリリースされました。このリリースには、より良いコードを作成できる新しい機能、関数または改善があります。本記事では、PHP 7.2の最も興味深い機能のいくつかをご紹介します。

更新:Kinstaのすべてのお客様に、PHP 8.0をご利用いただきるようになりました。

すべての機能については、「ご意見をお聞かせください。」ページをご確認ください。

コアの改善

引数型宣言

PHP 5以降、引数の型を指定することができます。値の指定した型が間違っていると、エラーが発生します。

引数型宣言型ヒントともいう)は関数またはクラスメソッドに渡されることが期待される変数の型を指定します。

次に例を示します。

class MyClass {
	public $var = 'Hello World';
}

$myclass = new MyClass;

function test(MyClass $myclass){
	return $myclass->var;
}

echo test($myclass);

このコードでは、テスト関数は instanceof MyClassを想定しています。間違ったデータ型を指定すると、次のような致命的なエラーが発生します。

Fatal error: Uncaught TypeError: Argument 1 passed to test() must be an instance of MyClass, string given, called in /app/index.php on line 12 and defined in /app/index.php:8

PHP 7.2以降では、型ヒントオブジェクトデータ型とともに使用することができる為、一般のオブジェクトを関数またはメソッドの引数として指定することができます。 次に例を示します。

class MyClass {
	public $var = '';
}

class FirstChild extends MyClass {
	public $var = 'My name is Jim';
}
class SecondChild extends MyClass {
	public $var = 'My name is John';
}

$firstchild = new FirstChild;
$secondchild = new SecondChild;

function test(object $arg) {
	return $arg->var;
}

echo test($firstchild);

echo test($secondchild);

この例では、各呼び出しで異なるオブジェクトを渡してテスト関数を2回呼び出しました。以前のPHPバージョンだと不可能なことです。

Dockerコマンド
DockerにてPHP7.0とPHP7.2のヒント型を試験する

オブジェクトの戻り値の型宣言

引数型宣言が関数の引数の期待される型を指定する一方、戻り値の型宣言は戻り値の期待される型を指定します。

オブジェクトの戻り値の型宣言 関数が返す変数の期待される型を指定します。

PHP 7.2以降では、オブジェクトデータ型の戻り値型宣言を使用することができます。 次に例を示します。

class MyClass {
	public $var = 'Hello World';
}

$myclass = new MyClass;

function test(MyClass $arg) : object {
	return $arg;
}

echo test($myclass)->var;

以前のPHPのバージョンでは、次の致命的なエラーが発生します:

Fatal error: Uncaught TypeError: Return value of test() must be an instance of object, instance of MyClass returned in /app/index.php:10

もちろん、PHP 7.2で「Hello World」が返ります。

パラメータ型の拡大

PHPでは、現在のところ、子クラスとその親クラスまたはインタフェース間でパラメータ型の分散が許可されません。どういう意味でしょうね。
下記のコードを考えてみましょう:

<?php
class MyClass {
	public function myFunction(array $myarray) { /* ... *
/ }
}

class MyChildClass extends MyClass {
	public function myFunction($myarray) { /* ... */ }
}

ここでは、サブクラスのパラメータを省略しました。PHP 7.0なら、このコードを使用してしまうと次の警告が発生します:

Warning: Declaration of MyChildClass::myFunction($myarray) should be compatible with MyClass::myFunction(array $myarray) in %s on line 8

PHP 7.2以降、コードを壊さずにサブクラスを省略することができます。これにより、すべてのサブクラスを更新せずに、ライブラリでタイプヒントを使用するようにクラスをアップグレードすることができます。

リスト構文の末尾のカンマ

配列内の最後の項目の末尾のカンマはPHPで有効な構文であり、新しい項目が追加しやすいくなり、カンマがないために発生する解析エラーが予防できますので、使用した方がいいです。PHP 7.2以降、グループ化された名前空間でも末尾のカンマが使用できます

リスト構文の末尾のカンマの詳細についてはこちらのRFCとコードの例をご参照ください。

セキュリティ改善

パスワードハッシュのArgon2

Argon2は強力なハッシングアルゴリズムであり、2015年のパスワード・ハッシング・コンクールの優勝者に選ばれ、PHP 7.2ではBcryptアルゴリズムのより安全な代替手段として提供されます。
PHPの新しいバージョンでは、password_ *関数で使用できるPASSWORD_ARGON2I定数が導入されています。

password_hash('password', PASSWORD_ARGON2I);

一方、Bcryptはコスト要因を1つしか処理できず、Argon2は以下の3つのコスト要因を処理できます。

  • ハッシュ処理中に使用されるKiBの数を指定するメモリコスト(デフォルト値は1 << 10、または1024 KiB、または1 MiBです)
  • ハッシュアルゴリズムの反復回数を指定する時間コスト(デフォルトは2回)
  • ハッシュ処理中に使用される並列スレッドの数を指定する並列度(デフォルトは2件)

3つの新しい定数がデフォルトのコスト要因を明確にしています:

  • PASSWORD_ARGON2_DEFAULT_MEMORY_COST
  • PASSWORD_ARGON2_DEFAULT_TIME_COST
  • PASSWORD_ARGON2_DEFAULT_THREADS

次に例を示します。

$options = ['memory_cost' => 1<<11, 'time_cost' => 4, 'threads' => 2];
password_hash('password', PASSWORD_ARGON2I, $options);

詳細については、Argon2 Password Hashをご参照ください。

PHPコアの一部としてのLibsodium

バージョン7.2以降、SodiumライブラリがPHPのコアに組み込まれています。Libsodiumは、暗号化、復号化、署名、パスワードハッシュ処理等のためのクロスプラットフォームの多言語ライブラリです。
ライブラリは以前PECLを通じて利用可でした。
Libsodiumの機能のリストについては、ライブラリのQuick Start Guideご参照ください。
または、「PHP 7.2:現代の暗号を標準ライブラリに追加する最初のプログラミング言語」も是非ご確認ください。

推奨されなくなるもの

以下はPHP 7.2で推奨されなくなり、PHP 8.0で削除される予定との機能・関数のリスト:

__autoload関数は、PHP 5.1のspl_autoload_registerに置き換えられました。今後、コンパイル中に見つけられたら、非推進通知が出ます。
$php_errormsg変数は、致命的でないエラーが発生したときにローカルスコープで作成されます。PHP 7.2以降は、代わりにerror_get_lasterror_clear_last を使用する必要があります。
create_function()では、生成された関数名、引数のリスト、および引数としての本体コードの関数の作成ができます。セキュリティ上またはパフォーマンス上の課題により推奨されなくなり、代わりにエンクロージャの使用が推奨されています。
mbstring.func_overload ini設定の0以外の値に設定されているものが推奨されなくなります。
(unset) キャストはnullにするだけのもので、役に立たないとみなされるとのことです。
parse_str() は、2番目の引数が指定されている場合はクエリ文字列を配列に解析するか、指定されていない場合はローカルシンボルテーブルに解析します。セキュリティ上の理由から、関数のスコープ内の変数をダイナミックに設定するのは推奨されない為、2番目の引数を無しのparse_str()を使用すると、非推進通知が出ます。
gmp_random() はプラットフォームに依存していると見なされ、推奨されなくなります。代わりにgmp_random_bits() と gmp_random_rage() をご使用ください。
each()foreach()のように配列を繰り返し処理するのに使われますが、foreach()の方は10倍も速いなどいくつかの理由から望ましいです。今後、ループの最初の呼び出しで非推奨通知が出ます。
assert()関数は、指定されたアサーションをチェックし、結果がFALSEの場合は適切な処理を行います。文字列引数を指定したassert()の使用法は、RCEの脆弱性を引き起こすため推進されなくなります。アサーション式の評価を防ぐために、 zend.assertion iniオプションを使用することができます。
$errcontextは、エラーが発生した時点で存在するローカル変数を含む配列です。 set_error_handler() 関数で設定されたエラーハンドラに最後の引数として渡されます。

PHP 7.2のWordPressユーザーへの影響は?

WordPressの正式分析ページによると、2018年3月現在、WordPressユーザーの19.8%しかPHP 7にアップグレードしていません。わずか5%がPHP 7.1を使用しています。ご覧のとおり、ユーザーの40%以上の大多数はまだPHP 5.6を使用しています。さらに面白いことに、ユーザーの39%以上がサポートのないPHPバージョンを使用しています。2016年12月に、WordPress.orgは推進されるバージョンをPHP 5.6~PHP 7以上にすることを広告しました。

WordPress PHP 7.1の分析データ
WordPress PHP 7.1の分析データ

PHP 7の方がはるかに高速であることが証明されているため、上記のデータはパフォーマンスの観点からも分かりにくいです。 次に分析データを示します。

  • 公式のPHPベンチマークでは、PHP 7をPHP 5.6と比較するとレイテンシがほぼ半分で、1秒あたり2倍のリクエストが実行されることが分かります。
  • Christian VighもPHPのパフォーマンス比較を公開し、PHP 5.2がPHP 7よりも400%遅いことが判明しました。

当社も、2018年にPHP 5.6対PHP 7 対HHVMの独自のパフォーマンスベンチマークを実行しました。上記のベンチマークと同様に、PHP 7.2ではPHP 5.6と比較して1秒あたりのトランザクション(要求)が3倍多く実行されることがわかりました。

WordPressのベンチマーク
WordPressのベンチマーク
  • WordPress 4.9.4 PHP 5.6 のベンチマーク結果:49.18 リクエスト/秒
  • WordPress 4.9.4 PHP 7.0 のベンチマーク結果:133.55 リクエスト/秒
  • WordPress 4.9.4 PHP 7.1 のベンチマーク結果:134.24 リクエスト/秒
  • WordPress 4.9.4 PHP 7.2 のベンチマーク結果:148.80 リクエスト/秒 ?
  • WordPress 4.9.4 HHVM のベンチマーク結果: 144.76 リクエスト/秒

第三者プラグインまたはテーマをすべて試験して正常に機能しているかを確認する理由で更新していない方も多いかもしれませんが、単純にまだできていないという方も多いでしょう。ご使用のPHPのバージョンが不明な方は、PingdomまたはGoogle ChromeのDevtoolsのようなツールを使って、簡単に確認できます。うことです。 HTTPリクエストの最初のヘッダーにはバージョンが表示されるはずです。

PHPバージョンを確認する
PHPバージョンを確認する

上記は、ホスティング会社がX-Powered-Byヘッダーの値を変更しない限りできます。変更している場合、PHPバージョンが表示されないことがあります、この場合、FTP経由でファイルをアップロードする必要があります。もちろん、直接にホスティング会社に問い合わせをし質問する手もあります。

PHP 7.2に更新する

PHP 7.2はまだリリーズされていませんが、リリーズ後はすぐに試験し始めた方がよいでしょう。WordPressウェブサイトをローカルで試験することも、コマンドラインからさまざまなバージョンのPHPを試験できるDockerのような環境でスクリプトを確認することもできます。

また、本番環境に一番近い為、ステージング環境をご利用することもできます。Kinstaは12月4日以降PHP 7.2をすべてのお客様を対象に利用可能にしています。ワンクリックでステージング環境を作成できます。

PHP 7.2をステージング環境にて試験する
PHP 7.2をステージング環境にて試験する

 

ステージングサイト用のPHPバージョンを「ツール」の「PHPエンジン」でワンクリックで選択でき、第三者プラグインとテーマとの互換性を保証するための試験を開始できます。すべてが機能していることが確認できたら、本番サイトもPHP 7.2に変更するか、ステージングサイトを本番サイトに反映することができます。

PHP 7.2への切り替え
PHP 7.2への切り替え

結論

あなたはPHP 7.2に切り替える準備ができましたか。今までに少なくともPHP 7への切り替えを行いましたね。切り替えていない方は、今でも試験をはじめませんか。スクリプトをアップグレードしてコードを確認し、PHP 7.2の最初の印象をお知らせください。

参照文献:PHPは死んだのか?

Carlo Daniele Kinsta

ウェブデザインとフロントエンド開発をこよなく愛し、WordPress歴は10年以上。イタリアおよびヨーロッパの大学や教育機関とも共同研究を行う。WordPressに関する記事を何十件も執筆しており、イタリア国内外のウェブサイトや雑誌に掲載されている。詳しい仕事情報はXとLinkedInで公開中。