Quantcast
Channel: PHP8タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 521

PHP8以降の比較とmatch文について

$
0
0
便利だけど使う前に挙動をしっかり理解しておきたいので。 予習メモです。 環境構築 PHP8の環境を用意します。 開発環境を汚したくない場合はDockerがおすすめです。 簡単なスクリプトならDockerfileを作成する必要もありません。 rmオプションを使用することにより、スクリプト実行後にコンテナが削除されます。 $ mkdir php8_test $ cd php8_test $ vi mytest.php $ docker run -it --rm --name my-running-script -v "$PWD":/usr/src/php8_test -w /usr/src/php8_test php:8.0-cli php mytest.php 公式ドキュメントにも紹介されています。 数値と文字列の比較 数値と文字列の比較について、文字列が数値形式か否かで変換の対象が変わります。 公式サイトより 数値形式の文字列と比較する場合は、PHP 8 は数値として比較を行います。それ以外の場合は、数値を文字列に変換し、文字列として比較を行います。 PHP7以前 'foobar'を数値に変換して比較します。 (int)'foobar'は0なので、結果がtrueになってしまいます。 公式サイトより 文字列が 数値形式の文字列 の場合は、対応する整数値に解決されます。 そうでない場合は、ゼロ (0) に変換されます。 mytest.php var_dump(0 == 'foobar'); //> bool(true) var_dump(in_array(0, ['foobar'])); //> bool(true) PHP8以降 'foobar'は数値形式の文字列ではないので、0を文字列に変換して比較します。 (string)0は'0'なので、結果はfalseになります。 mytest.php var_dump(0 == 'foobar'); //> bool(false) var_dump(in_array(0, ['foobar'])); //> bool(false) match式 PHP8から追加されたmatch式を紹介します。 「厳密な比較ができるswitch文」として利用できそうです。 公式サイトより match 式は、値の一致をチェックした結果に基づいて評価結果を分岐します。 switch 文と似ていますが、 match 式は複数の候補と比較される制約式を持ちます。 switch 文とは異なり、 三項演算子のように値を評価します。 switch 文とは異なり、 弱い比較(==)ではなく、 型と値の一致チェック(===) に基づいて行われます。 $return_value = match (制約式) { 単一の条件式 => 返却式, 条件式1, 条件式2 => 返却式, }; PHP7以前 ご存知のとおり、switch文では厳密な比較(===)が行われません。 mytest.php $param = 1; # switch文 switch ($param) { case '1': str_func(); break; case 1: int_func(); break; default: default_func(); } //> Param is string! function str_func() { echo "Param is string!\n"; } function int_func() { echo "Param is integer!\n"; } function default_func() { echo "Default!\n"; } そのため、条件分岐で厳密な比較を行う場合はif文や三項演算子を利用する必要がありました。 mytest.php # if文 if ($param === '1') { str_func(); } elseif ($param === 1) { int_func(); } else { default_func(); } //> Param is integer! # 三項演算子 $param === '1' ? str_func() : ($param === 1 ? int_func() : default_func()); //> Param is integer! match式の使いどころ 「本当はswich文を使いたいけれど厳密な比較が出来ないから使えない・・・ぐぬぬ・・・」のような分岐が多い処理で役に立ちます。 下記コードのように$paramの種類ごとに処理が存在する場合は活躍できそうです。 また、記述できるのは一行の式だけですがbreak;が必要ないためコードがスッキリします。 mytest.php match ($param) { '1' => str_func(), 1, => int_func(), default => default_func(), }; //> Param is integer! 逆に分岐が少ない場合はさほどメリットが無いかもしれません。 match式で厳密な比較を行わない方法 興味深い使い方もありました。 公式サイトより 制約式に true を指定することで、 厳密な一致チェックを行わずに match 式を使うことができます。 下記コードは制約式にtrueを指定しているため、条件式のin_array($param, $str_arr)の結果を元に条件分岐が行われます。 ですがin_arrayの第3引数にtrueが指定されていないので厳密な比較が実行されず、match式の結果にもそれが反映されてしまいます。 mytest.php $param = 1; $str_arr = ['1', '2']; $int_arr = [1, 2]; // 制約式にtrueを指定 match (true) { in_array($param, $str_arr) => str_func(), in_array($param, $int_arr) => int_func(), default => default_func(), }; //> Param is string! この場合は条件式で厳密な比較を行う必要があります。 mytest.php match (true) { in_array($param, $str_arr, true) => str_func(), in_array($param, $int_arr, true) => int_func(), default => default_func(), }; //> Param is integer! 新しい機能は使いたくなるのが人の常ですが、使いどころは見極めていきたいです。

Viewing all articles
Browse latest Browse all 521

Trending Articles