今日も適当ダイアリー

PHP や Javascript や Symfony、BEAR.Sunday などのWeb周りのことを中心に。それ以外のことも気まぐれに投稿します。

PHPは型がないのではなく、自動型変換を行ってくれる言語です

PHPの長所と短所の両方としてあげられる項目として、「PHPは型を意識せずにプログラミングできる」というようなことが言われる場合があります。
PHPは、基本的に場合に応じて、型を自動的に変換(キャスト)するため、初心者にとって入りやすいポイント、とも言えるし、何らかの事態の際にはまりやすいポイントとも言えると思う。
ここで大切なのは、型がない訳ではなく、内部的に自動的に変換しているだけで、実際には明確に型がある、ということだ。
たとえば、こんなソースを書いたとしよう。

<?php
    // search_word に値があれば
    if ($_GET['search_word']) {
        // 処理を行う
    }

条件判定文で、変数に値があるかどうかを判定しているのだが、この_GET変数はGET値が自動的に代入されているため、文字列型(string)(もしくは未定義値)が入る。
で、この変数が、未定義だった場合や、空文字("")の場合は、($_GET['search_word']) は false になるので、正常な挙動である。
ただし、"0"が入っていた場合も false になってしまうのである。
PHP: 論理型 (boolean) - Manual
"0"の場合は true になるべきなら、

<?php
    // search_word に値があれば
    if ($_GET['search_word'] != "") {
        // 処理を行う
    }

としなければならない。

なお、下記のように、数値形式の文字列の場合は、数値として解釈され、両方ともtureになってしまうので、注意が必要だ。

<?php
    if ("58" == "0x3A") {
        echo "true";
    }

    if ("0.01" == "1e-2") {
        echo "true";
    }

このような場合には、「===」(値と型の両方が一致する=自動的な型変換が行われずに評価される)演算子を使わなければならない。


また、数値と文字列の比較も注意が必要。

<?php
    if (0 == "hoge") {
        echo "true";
    }

    if (1 == "1hoge") {
        echo "true";
    }

    if (1 == " 1hoge") {
        echo "true";
    }

    if (1 == "1.0hoge") {
        echo "true";
    }

    if (1 == " 1hoge") {
        echo "true";
    }

    if (58 == "0x3Ahoge") {
        echo "true";
    }

これらは全てtrueに評価される。
なぜなら、数値と文字列の比較の場合は、文字列を数値に型変換して比較が行われるからである。
文字列の数値への変換規則については、PHP: 文字列 - Manualを参照しよう。

これらを回避するためには、状況に応じて、「===」を使うとか、数値をstring型へキャストするとか、strcmp関数を使うとかする必要がある。


意外に、この自動的な型変換ではまるケースがあるので、きちんと意識する必要がある。
きちんと、型の比較について理解しよう。
http://jp.php.net/manual/ja/types.comparisons.php