Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

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. 参考

cyrt
お仕事ではPHPを書いています。 | 医療事務 → Web系PG → 医療系IT | PHP/Laravel、Ruby、Excel/VBA
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした