dockerを使用してさくっとPHP8を触ってみた
PARONYM Advent Calendar 2020 - Qiita の2日目です。
はじめに
2020/11/26にPHP8がリリースされました。
ということで、自身のローカル環境をなるべく汚さずにPHP8の新機能を触ってみることにしました。
前提条件
- dockerがインストールされていること
きっかけ
PHP8の新機能を触ってみたい!でも自身のPCを汚したくない!
PHP8を試す環境として、当然ながらプロダクトの開発環境で試すわけにはいきません。(本番環境なんて以ての外)
となるとローカルPCで試すのが妥当ですが、インストールや設定の手間、もしもの時のバージョンの切り替えを考えると一気に面倒になります。
今回はPHP8の機能を触るのが目的であり速度性能を試すわけではないため、さくっとdockerを使用してPHP8を実行することにしました。
コード
今回試したコードは全てGithubにコミットしています。
https://github.com/y-kakinuma-paronym/php8-docker
dockerでPHP8の実行
$ docker run --rm -v `pwd`:/app -w /app php:8.0-rc php {実行したいファイル}
- PHPの実行後、コンテナは削除する :
--rm
- カレントディレクトリをコンテナの/appにマウント :
-v `pwd`:/app
- コンテナ内の作業用ディレクトリは/app :
-w /app
- dockerイメージは
php:8.0-rc
を使用 - php実行 :
php {実行したいファイル}
毎回コマンドを打つのは面倒なのでシェルスクリプトを作成しておくと楽です。
#!/bin/sh
docker run --rm -v `pwd`:/app -w /app php:8.0-rc php $1
# ./exec_php.sh match_expression.php
PHP8新機能
PHP8の新機能はここから抜粋しています。
PHP: PHP 8.0.0 Release Announcement
Named arguments
引数を渡すときに名前を指定できるようになりました。
https://wiki.php.net/rfc/named_params
<?php
// Named arguments
// https://wiki.php.net/rfc/named_params
$str = "<a href='test'>Test</a>";
// PHP7
// $result = htmlspecialchars($string, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);
// PHP8
// double_encodeの引数のみをデフォルト引数から変更したい場合、引数の名前を指定する
$result = htmlspecialchars($str, double_encode: false);
echo $result . "\n"; // <a href='test'>Test</a>
?>
Constructor property promotion
コンストラクタでのプロパティ初期化が簡略化できるようになりました。
https://wiki.php.net/rfc/constructor_promotion
<?php
// Constructor property promotion
// https://wiki.php.net/rfc/constructor_promotion
class Point {
// PHP8
public function __construct(
public int $x = 0,
public int $y = 1,
public int $z = 2,
) {
print "Point constructor\n";
}
// PHP7
// public int $x;
// public int $y;
// public int $z;
// public function __construct(
// int $x = 1,
// int $y = 2,
// int $z = 3
// ) {
// $this->x = $x;
// $this->y = $y;
// $this->z = $z;
// }
public function showClassParameter() {
print_r([$this->x, $this->y, $this->z]);
}
}
$obj = new Point();
$obj->showClassParameter();
?>
Union types
共用体型(union type)が追加されました。
https://wiki.php.net/rfc/union_types_v2
<?php
declare(strict_types=1);
// int と string を型指定
$f = function (int|string $v) {
var_dump($v);
};
$f(100); // ok
$f("abc"); // ok
$f(true); // ng
Match expression
<?php
// Match expression
// https://wiki.php.net/rfc/match_expression_v2
switch (1) {
case 0:
$result = "Foo\n";
break;
case 1:
$result = "Bar\n";
break;
case 2:
$result = "Baz\n";
break;
}
echo $result; // Bar
/**
* switchとの違い
* ・一致した結果を変数に代入することが可能
* ・一致は一つのみをサポート。breakなどは必要なし
* ・一致は厳密な比較
*/
echo match(1) {
0 => "Foo\n",
1 => "Bar\n",
2 => "Baz\n"
};
// Bar
echo match (8.0) {
'8.0' => "Oh no!",
8.0 => "This is what I expected",
};
// This is what I expected
// ↑厳密な比較のため
?>
switchとの違いについての説明はコード内に記載しています。特に注意が必要なのが、一致は厳密な比較であるところです。
Nullsafe operator
null演算子が追加されました。
https://wiki.php.net/rfc/nullsafe_operator
<?php
// Nullsafe operator
// https://wiki.php.net/rfc/nullsafe_operator
class Session
{
public $user = null;
}
$session = new Session();
/**
* nullsafe演算子「?」を用いることでチェーン内の1つの要素で評価が失敗すると、
* チェーン全体の実行が中断され、nullを返す
*/
$country = $session->user?->getAddress()?->country;
var_dump($country) // null
?>
$session->user?->getAddress()?->country;
例では↑のuser
がnullのため失敗となり、nullsafe演算子はnull
を返します。
PHP8の所感
PHP8の目玉はなんと言ってもJITコンパイラーによる処理の高速化ですが、こういった細かい機能も実装が楽になるため嬉しい追加でした。
特にMatch expressionは、JSONを作成するためにarrayを組み立てるときに三項演算子より複雑な分岐ができるため非常に便利だと思います。
$result = 1;
$json = [
"resutl" => match($result) {
0 => "Failed",
1 => "Success",
2 => "No Updated"
},
];
echo json_encode($json); // {"resutl":"Success"}
Nullsafe operatorもうまく利用できれば、if文が減りコードの可読性を向上させることができそうです。
まとめ
今回はPHP8の新規機能をDockerを使用して自身のPCをなるべく汚さずに試してみました。
今回紹介していないPHP8の新機能はまだまだありますので、公式サイトを参照してください。
PHP: PHP 8.0.0 Release Announcement
Dockerを利用すれば、PHP8に限らず様々な環境を楽に構築できるのでこれからもどんどん利用していきたいと思います。