strpos()が0を返すと if文でfalseと同じに扱われてしまう
strpos()は文字列が先頭(添字0)で見つかった場合、戻り値の0を返します。if ($pos)のように真偽値として直接判定すると、0はfalseとして扱われるため、先頭で見つかったのに「見つからなかった」と誤判定します。
なぜエラーが出ないのか
出力: not found
(エラーなし)- PHPは何も報告しません。文法として正しいためです
出力: not found- 実際の挙動 — 期待した結果と食い違っている箇所
見つけ方- エラーが出ないので、出力を目で確かめるか、コードを目で追うしかありません。この種の誤りが最も発見が遅れます
このエラーが出る典型パターン
パターン1
1 <?php 2 $haystack = "hello world"; 3 $pos = strpos($haystack, "hello"); 4 if ($pos == false) { ^ 5 echo "not found"; 6 } else { 7 echo "found"; 8 }
出力: not found期待: found (エラーにはなりません、実際は先頭=添字0で見つかっています)
strposは"hello"を添字0で見つけたため0を返します。==で比較すると0とfalseは等しいとみなされ、見つかっているのに「not found」と誤判定します。型まで比較する===が必要です。
直し方: == を === にします。
広告
広告スロット(未設定)
パターン2
1 <?php 2 $text = "abc123"; 3 $pos = strpos($text, "abc"); 4 if ($pos ) { ^ 5 echo "found at start"; 6 } else { 7 echo "not found"; 8 }
出力: not found期待: found at start (エラーにはなりません)
strposは先頭(添字0)で見つかると0を返しますが、if ($pos)は0をfalseとして扱います。$pos !== falseのように型まで比較する必要があります。
直し方: $pos を $pos !== false にします。
パターン3
1 <?php 2 $url = "https://example.com"; 3 $pos = strpos($url, "https"); 4 if ($pos ) { ^ 5 echo "secure"; 6 } else { 7 echo "not secure"; 8 }
出力: not secure期待: secure (エラーにはなりません)
"https"は0番目で見つかるため$posは0です。if ($pos)はfalsyな0として扱ってしまうので、!==falseで比較する必要があります。
直し方: $pos を $pos !== false にします。
よくある誤解
「0以上の値が返ってきたなら見つかったはず」という思い込みは、if文でそのまま真偽判定すると崩れます。PHPの0は偽として扱われるため、必ず===falseで比較する必要があります。
まとめ
strpos()が0を返すと if文でfalseと同じに扱われてしまうは中級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。