文字列を考慮した数値演算処理分岐


CSVでWordPressにデータを流し込み、ランプ名のキーワードでAPIかけて画像とかブログとか楽天の情報を引っ張ってくるんだけど、CSVの標準価格に”オープン”といれると、実際のコンテンツには、”標準価格 0円”と表示されてしまうことが判明。

これって、税抜きの値段に消費税の5%をかけて表示させているんだけど、”オープン”といれると書式が文字列になって、それにかけ算するものだから0になってしまうらしい。

こうすると若干ではあるもののスッキリするような気がPHP素人の私にはする.なんとなく + 0 以外にも軽量な数値変換手段がある気がするし,もっと効率の良い方法があるような気もする.数値型と文字列型の変換コストがよく判っていないもので.

<?php

$listPrice = "1";
$listPrice = "オープン";

if ((string)($listPrice + 0) === $listPrice) {
        echo $listPrice * 1.05;
} else {
        echo "オープン";
}

?>

仕組み

加算演算子では,オペランドに float が含まれるとき以外は結果が整数となると仕様にある.
よって,$listPrice + 0 の結果は,$listPrice が "オープン"のとき整数型の 0,"1"のとき整数型の 1 となる.その結果をstring で強制的に型変換するので,結果は "0" または "1".

=== 演算子は事前の型変換を行わない比較なので,文字列が数値表記であってもそのまま比較.
$listPrice = "オープン"のときは ("0" === "オープン") なので結果は false.$listPrice = "1" のときは,("1" === "1")となるので,true.

浮動小数点数についても,問題なく動く.$listPrice が浮動小数点数に変換され,+演算子の結果も浮動小数点になる.

よくわかんないこと

このコード,手元のOSX付属の5.3.6では,下記のように替えても動いてしまう.

if ((string)($listPrice + 0) == $listPrice) {

== は,型の相互変換を行う.左辺は数値形式の文字が含まれることが自明.マニュアルの比較演算子の項を見ると,数値が文字列に変換されるはずなのだが.

まあもっとも,同マニュアルの== による緩やかな比較表を見ると,期待されている挙動らしい.

わけわからん.

結論

型周りでこの手の落とし穴が山盛りなので,PHPはニガテ.仕事では絶対に使いたくない….

オチ

ブツクサ言いながら,久しぶりにマニュアル読んでいたら,is_numeric ってのがあるじゃないの… orz.
でも書いちゃったから残しておく.