比較演算と文字列の比較

目次
  • 解説
  • 1. 学習の準備
  • 2. 条件式と比較演算式
  • 3. 比較演算子
  • 4. 文字列の比較
問題に挑戦!
進捗を変更する




解説

1. 学習の準備


下表のとおり学習用のクラスを作成して、その中にmainメソッドを作っておきましょう。

ファイル名Condition.php
クラス名Condition

2. 条件式と比較演算式


PHPにおける(しき)のひとつである条件式は、「基本構文 > 型・変数・定数 > > 正しい?正しくない?」で学習した通り、「もし~ならば」という条件文の「」の部分を比較によって示した式のことでした。

改めて「映画のチケットを販売するシステム」を例にとって考えてみましょう。「もし満席ならば売り切れと表示する」という条件文に対し、「満席」という部分を言い換えると、「販売済みチケット数と座席数が同じ」となります。これを条件式にすると、以下のコードの5行目の右辺となるのでしたね。

    static function practiceBoolean() {
        $theatreSheetsCount = 120;
        $soldTicketsCount = 119;
        // 販売済みチケット数と座席数を「==」で比較する式の結果を代入
        $isSoldOut = ($soldTicketsCount == $theatreSheetsCount);
        if ($isSoldOut) {
            Logger::echo('売り切れです!');
        } else {
            Logger::echo('販売中です!');
        }
    }

この条件式の核となる比較を行う部分$soldTicketsCount == $theatreSheetsCount」のことを比較演算式と呼びます。このケースでは、条件式は比較演算式1つのみで構成されています。

なお、比較演算式の結果を出すことを評価するといい、評価の結果は必ず論理値型bool型)の「true」か「false」となります。

3. 比較演算子


比較演算式の中で「同じかどうか」を示す「==」のことを比較演算子と言い、下表のような種類があります。

比較演算子用例比較結果
==A == BAがBと等しければ true
イコールと読む
!=A != BAがBと等しくなければ true
ノットイコールと読む
>A > BAがBを超過していれば true
大なりと読む
<A < BAがB未満であれば true
小なりと読む
>=A >= BAがB以上であれば true
大なりイコールと読む
<=A <= BAがB以下であれば true
小なりイコールと読む

以下・以上は、AとBが等しい場合も true となりますが、超過・未満の場合はAとBが等しい場合には true となりませんので、次のサンプルコードを確認して、正しく使い分けられるようにしましょう。ブラウザから「http://localhost/php_basic/Condition.php」を確認してください。

    static function practiceCompare() {
        $theatreSheetsCount = 120;
        $soldTicketsCount = 119;
        Logger::echo('soldTicketsCount:' . $soldTicketsCount);
        self::checkSoldOut($soldTicketsCount == $theatreSheetsCount);
        self::checkSoldOut($soldTicketsCount != $theatreSheetsCount);
        self::checkSoldOut($soldTicketsCount > $theatreSheetsCount);
        self::checkSoldOut($soldTicketsCount < $theatreSheetsCount);
        self::checkSoldOut($soldTicketsCount >= $theatreSheetsCount);
        self::checkSoldOut($soldTicketsCount <= $theatreSheetsCount);
        $soldTicketsCount = 120;
        Logger::echo('soldTicketsCount:' . $soldTicketsCount);
        self::checkSoldOut($soldTicketsCount == $theatreSheetsCount);
        self::checkSoldOut($soldTicketsCount != $theatreSheetsCount);
        self::checkSoldOut($soldTicketsCount > $theatreSheetsCount);
        self::checkSoldOut($soldTicketsCount < $theatreSheetsCount);
        self::checkSoldOut($soldTicketsCount >= $theatreSheetsCount);
        self::checkSoldOut($soldTicketsCount <= $theatreSheetsCount);
        $soldTicketsCount = 121;
        Logger::echo('soldTicketsCount:' . $soldTicketsCount);
        self::checkSoldOut($soldTicketsCount == $theatreSheetsCount);
        self::checkSoldOut($soldTicketsCount != $theatreSheetsCount);
        self::checkSoldOut($soldTicketsCount > $theatreSheetsCount);
        self::checkSoldOut($soldTicketsCount < $theatreSheetsCount);
        self::checkSoldOut($soldTicketsCount >= $theatreSheetsCount);
        self::checkSoldOut($soldTicketsCount <= $theatreSheetsCount);
    }

    static function checkSoldOut(bool $isSoldOut) {
        if ($isSoldOut) {
            Logger::echo('売り切れです!');
        } else {
            Logger::echo('販売中です!');
        }
    }
[2020/12/31 12:34:56] soldTicketsCount:119
[2020/12/31 12:34:56] 販売中です!    // 119 == 120 ⇒ false
[2020/12/31 12:34:56] 売り切れです!  // 119 != 120 ⇒ true
[2020/12/31 12:34:56] 販売中です!    // 119 >  120 ⇒ false
[2020/12/31 12:34:56] 売り切れです!  // 119 <  120 ⇒ true
[2020/12/31 12:34:56] 販売中です!    // 119 >= 120 ⇒ false
[2020/12/31 12:34:56] 売り切れです!  // 119 <= 120 ⇒ true
[2020/12/31 12:34:56] soldTicketsCount:120
[2020/12/31 12:34:56] 売り切れです!  // 120 == 120 ⇒ true
[2020/12/31 12:34:56] 販売中です!    // 120 != 120 ⇒ false
[2020/12/31 12:34:56] 販売中です!    // 120 >  120 ⇒ false
[2020/12/31 12:34:56] 販売中です!    // 120 <  120 ⇒ false
[2020/12/31 12:34:56] 売り切れです!  // 120 >= 120 ⇒ false
[2020/12/31 12:34:56] 売り切れです!  // 120 <= 120 ⇒ false
[2020/12/31 12:34:56] soldTicketsCount:121
[2020/12/31 12:34:56] 販売中です!    // 121 == 120 ⇒ false
[2020/12/31 12:34:56] 売り切れです!  // 121 != 120 ⇒ true
[2020/12/31 12:34:56] 売り切れです!  // 121 >  120 ⇒ true
[2020/12/31 12:34:56] 販売中です!    // 121 <  120 ⇒ false
[2020/12/31 12:34:56] 売り切れです!  // 121 >= 120 ⇒ true
[2020/12/31 12:34:56] 販売中です!    // 121 <= 120 ⇒ false

結果をよく見ると、soldTicketsCount121になり得ないならば、「==」と「>=」で正しい表示となり、soldTicketsCount121になり得るならば「>=」のみが正しい表示となることがわかります。

4. 文字列の比較


文字列も「==」で比較することができますが、数値と文字列を比較する際などに内部で暗黙的な型変換をおこなうため、意図した結果にならないパターンがあります。

    static function practiceEquals() {
        $intA = 1;
        $stringA = '01';
        $result = ($intA == $stringA); // stringAの値「'01'」をint型(「1」)に変換後、比較をおこなう
        if ($result) {
            // resultがtrueならばこのブロックを実行する
            Logger::echo('result は true です!');
        } else {
            // resultがfalseならばこのブロックを実行する
            Logger::echo('result は false です!');
        }
    }
[2020/12/31 12:34:56] result は true です!

このように、PHPでは「==」による比較の場合、まず内部で両辺の型を揃えてから比較を行います。そのため、int型の「1」と、string型の「01」を比較した際に、両者の値が等しい = true の値が返ってきてしまいます。下に型変換の例をいくつか記載します。

    static function practiceTypeConversion() {
        $variable = '1.1 + 1.1';
        Logger::echo($variable);
        Logger::echo((int) $variable);
        Logger::echo((float) $variable);
        Logger::echo((bool) $variable);
    }
[2020/12/31 12:34:56] 1.1 + 1.1 // string型
[2020/12/31 12:34:56] 1         // int型に変換
[2020/12/31 12:34:56] 1.1       // float型に変換
[2020/12/31 12:34:56] 1           // bool型に変換

echo関数自体が、値をstring型に変換して画面に出力をおこなうため、6行目などは「1.1 + 1.1(string型))」「false(bool型)」「1(string型)」とかなり直感に反した変換がおこなわれてしまいます。

このようにPHPの型変換ルールはとても複雑なので、仕様を把握して意図的に使用する場合を除き、以下の「===」による厳密な比較を使用するようにしましょう。

    static function practiceEquals() {
        $intA = 1;
        $stringA = '01';
        $result = ($intA === $stringA); // 「==」ではなく「===」を使用する
        if ($result) {
            // resultがtrueならばこのブロックを実行する
            Logger::echo('result は true です!');
        } else {
            // resultがfalseならばこのブロックを実行する
            Logger::echo('result は false です!');
        }

        $stringA = 'DigSkill';
        $stringB = 'Dig' . 'Skill';
        $result = ($stringA === $stringB); // 「==」ではなく「===」を使用する
        if ($result) {
            // resultがtrueならばこのブロックを実行する
            Logger::echo('result は true です!');
        } else {
            // resultがfalseならばこのブロックを実行する
            Logger::echo('result は false です!');
        }
    }
[2020/12/31 12:34:56] result は false です!
[2020/12/31 12:34:56] result は true です!

===」を使用することで型を含めて、値が一致するか比較することができます。

問題

確認問題


確認問題

この中でコメントが示す比較演算式の表記として正しくないものはどれか?