PHP でのゼロ (0) による文字列比較


問題



PHP で任意の文字列をゼロ (0) と比較すると、奇妙なことが起こります.まずはこれを見せてください.次に、「なぜ?」を知ることになります.

<?php
var_dump(0 == "something");        // bool (true)


それは奇妙ではありませんか? switch ケースを使用した別のアプローチで、この奇妙な動作をお見せしましょう.このコードを実行する前に、指を交差させてください.

<?php
switch ("something") {
case 0:
    echo "Strange";
    break;
case "something":
    echo "All is well";
    break;
}

// Strange    WTF??


何が起こっている? All is well, n't it? と表示されるはずです.では、なぜ PHP はこの種の出力を表示するのでしょうか?さらに、この種の出力は、コードにバグを作成する可能性があります.この種のバグは、上記のコードのような in_array() または switch ステートメントなど、比較が暗黙的である場合によく発生します. in_array() の状況で何が起こったか見てみましょう:

<?php
$languages = ["C", "C++", "PHP",];
$value = 0;
var_dump(in_array($value, $languages));         // bool(true)


出来事



2008年に公開された映画「ハプニング」を見ましたか?物語は、神秘的な有毒な空気についてであり、人々が自殺する原因となります.映画については話さないで、今は有毒なコードの出来事について話す必要があります.では、これは PHP でどのように行われたのでしょうか.

PHP では、文字列を数値と比較する場合、php の非厳密な比較セマンティクスにより、文字列は数値に変換されます.つまり、厳密モードでは === を使用すると型と値が比較されますが、非厳密モード (==) では値のみが比較されます.その場合、値の型は整数に変換されます.これが、php が実行されるプロセスです.では、どの文字列が何に変換されたのか確認してみましょう.

<?php
var_dump((int) "0");                // int(0)
var_dump((int) "01");               // int(1)
var_dump((int) "10");               // int(10)
var_dump((int) "something");        // int(0)


暗黙の変換の魔法があります.これで、数値文字列が整数に変換されることがわかりましたが、通常の文字列になるとゼロ (0) に変換されます.ご覧のように、「何か」がゼロ (0) に変換されると、値が等しくなるので、“something” == 0 の出力は true になります.

救世主



では、PHP 8 である The Savior を紹介します.PHP 8 は、適切なルールでこの問題を解決します.これから、文字列から数値への暗黙的な変換に関しては、PHP は最初に文字列が数値文字列かどうかをチェックします.数値文字列の場合、文字列は数値に変換されます.それ以外の場合は false を返します.

0 == something             // false  [in php 8]
0 == something             // true   [in php 7]