どうも、katです。
今回は、PHPの型についてのお話になります。
PHPでは、(int)などを変数の前につけることで、変数の型をcastすることができます。
公式に記載のcastの種類は以下になります。
- (int), (integer) – 整数へのキャスト
- (bool), (boolean) – 論理値へのキャスト
- (float), (double), (real) – float へのキャスト
- (string) – 文字列へのキャスト
- (array) – 配列へのキャスト
- (object) – オブジェクトへのキャスト
- (unset) – NULL へのキャスト (PHP 5)
今回は、この中で、整数へのcastについて書いていこうと思います。
int型には上限値がある
早速、結論になりますが、int, integerへcastには、上限値が存在します。
具体的には、PHP_INT_MAXという定数で上限値が定義されています。
var_dump(PHP_INT_MAX);
などとすると、上限値が表示されます。
この値は、環境によって異なります。
具体的には
- システムのbit数(32 or 64bit)
- PHPのバージョン
によって、MAX値が異なります。
基本的には、システムが32bitの場合は、2147483647、64bitの場合は9223372036854775807が上限値となります。
例外として、Windowsの場合は、PHPのバージョンが7以前の場合は、32bitと同じ2147483647が適用されるみたいです。(6.5で確認済)
floatへの自動castに注意!
int型の上限値を超えた場合、自動的にfloat型にcastされますが、float型については、PHPのバージョンによって、castのされ方が異なりますので、注意が必要です。
例えば、
PHP_INT_MAX + 1025
と、
PHP_INT_MAX
が等しいと判断される場合があります(PHP7で実証。PHP6.5では再現せず)
なので、桁数の多い値を安易に比較するのはリスクが高いと言えます。
だからと言って、比較する際に、
(int)$num1 == (int)$num2
のように、(int)でcastしたとしても、PHP_INT_MAXを超える値が入ってきた場合に、正しくcastされず、おかしな比較結果となってしまいます。
対処方法
そもそも、PHP_INT_MAXを超えるような大きな値を保持しないように設計することが第一です。
とは言え、そうもいかない場合もあるかと思いますので、大きい数値を扱う場合は、以下に気をつけて実装することで、問題なく扱うことができるでしょう。
・本番サーバーは、PHP7もしくは、Windows以外のサーバーかつ64bitとすること
・バリデーションで、入力値を18桁までとする(もっと少なくても問題ないです)
どうしても上記の条件をクリアできないということでしたら、バリデーションで9桁までとする必要があります。
最後に
いかがだったでしょうか。
intやfloat周りは、環境や、PHPのバージョンによって挙動が変わる部分でもあり、よく知らずに実装してしまうと、環境によって挙動がおかしいなど、バグの原因になりかねませんので、気をつけましょう。
以上、「PHPのint型にcastする際は上限値に注意しよう!」でした〜。