LoginSignup
2
1

More than 5 years have passed since last update.

[PHP] 数値と文字列の比較で悩んでいる話

Last updated at Posted at 2018-05-10

1. はじめに

4月からPHPを書いています。if文による真偽判断で、数値と数値表記の文字列を比較するコードを書いた際、少し苦しんでしまい、しかしキレイな解決策を思いつかなかったお話です。

2. どんなコードを書こうとしたのか

Webシステムの入力フォームで、プルダウンリスト <select> とその選択肢 <option> を生成する箇所です。遷移元の画面の入力値をPOSTで受取り、POSTで受取った値に該当する選択肢には selected="selected" を付加し、初期値として表示します。
POST値が null のときは、selected="selected" である選択肢がないため、一番上の「未選択」が初期表示になる、という寸法です。

<select name="pulldownlist">
<option>未選択</option>
<?php
/*
 * $list_items は選択肢の配列。
 * $key はゼロからの連番。
 * $post_value は文字列型の数字か null。
 */
foreach($list_items as $key => $value) {
    if($post_value == $key) { // == で比較していた
        echo "<option value=${key} selected=\"selected\">${value}</option>";
    } else {
        echo "<option value=${key}>${value}</option>";
    }
}
?>
</option>

このような例で、POST値は null なのに $key0 の選択肢が初期表示されるという状態になり、他の箇所のコードがおかしいのかなあと探し回ったのですが、結局原因は if 内の == による比較でした。

3. 悩みどころと解決策

PHPでは ==暗黙の型変換をするんですね。かといってこういうケースの場合、 === でもうまくいきません。

<?php
/*
 * null と 0 の比較は false に、"1" と 1 の比較は true になってほしい。
 */

// == を使うと…どちらも真になる!
null == 0;  // => true
"1"  == 1;  // => true

// === を使うと…どちらも偽になる!
null === 0; // => false
"1"  === 1; // => false

どうするのが正解なのかしばらく考えた挙げ句、コードは汚く見えますが、止むを得ず次のように書くことにしました。

<?php
// キャストしたうえで === による厳密比較
null === (string)0; // => false
"1"  === (string)1; // => true

こうすれば、POST値が空の場合と値が入っている場合のいずれにも対応ができます。

4. おわりに

キャストを使うなんて…なんだかもうちょっとスクリプト言語らしく(?)書きたいところだったよな~と思いつつも、結局キャストに落ち着いてしまいました。初期値の表示もするプルダウンリストをつくるなんて、ザラにあると思うんですが、今後もこう書いていく、のか…?
もっといいスマートな解決法がありましたら、ご指南いただけますとうれしいです。

単純な比較演算で悩むとは思わなかったので、今回記事に書いてみた次第です。

5. 参考

2
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1