数値がMySQLのint(11)に保存できない!PHPの変数が本当にint型か確認!
数値なのにMySQLのint(11)に保存できない!「The provided value is invalid」のエラーが出る理由とその対処方法の解説
PHPで数値を int(11)に保存しているのにエラーとなった経緯
LAMP環境(Linux、Apache、MySQL、PHPの環境。いわゆる Web環境)で、商品を販売し、その販売手数料をデータベースに保存する、という仕組みを作りました。
具体的には...
「商品の価格($price):100,000円」の商品を
「販売手数料率($rate):20%」として手数料を計算し
その手数料を「fee int(11)」というカラムに保存する
というものです。
これを処理するため、下記の処理を作成しました(言語は PHPです)。
1 2 3 4 5 |
$price = 100000; $rate = 20; $rate_percent = $rate / 100; $fee = $price * $rate_percent; |
この処理の結果の「$fee」をテーブルの「fee int(11)」カラムに保存する処理を作成しました。
しかし、テーブルに保存する処理で MySQLが「The provided value is invalid」のエラーを出力するのです。
「$fee」に入っている値は「20000」という数値なのにも関わらず!です。
それはそれはもう悩みましたよ。
検証ソースコード・その1
この問題を確認するために下記のソースコードを作成しました。
1 2 3 4 5 6 7 8 9 10 11 12 |
$price = 100000; $rate = 20; $rate_percent = $rate / 100; $fee = $price * $rate_percent; echo $fee; if(is_int($fee)){ echo "INTです"; } else { echo "INTではありません"; } |
さて問題です!
この場合「INTです」「INTではありません」のどちらになるでしょうか?
問題にするくらいなので、「INTではありません」と出てくると考える方もあるかもしれませんが、理由はお分かりになりますか?
検証ソースコード・その2
では、下記のように記述した場合はどうでしょうか?
1 2 3 4 5 6 7 8 9 10 11 |
$price = 100000; $rate = 20; $fee2 = $price * $rate / 100; echo $fee2; if(is_int($fee2)){ echo "INTです"; } else { echo "INTではありません。"; } |
その1と2の違いは、あらかじめ手数料率を計算して変数「$rate_percent」に入れているか、いないかの違いです。
「$fee」「$fee2」のいずれも「echo」で出力される値は「20000」なのですが、
前者は「INTではありません」となります。
後者は「INTです」となります。
理由は、
後者は、変数はすべて「int」であり、計算結果も「int」であるため、最終的な変数である「$fee2」も「int」になります。
対して、前者は変数「$rate_percent」に代入される値「0.2」が「int」ではない値(double)となります。
そのため、「int」に「intではない値(double)」をかける計算をする事になり、計算結果の見た目が「int」であったとしても「$fee」は「intではない(double)」となるのです。
PHPで integerと doubleの計算をする際の対策
今回のような integerと doubleの計算をする際の対策としては、キャスト演算子を使って型を指定する必要があります。
今回の場合は、下記のような表記にすることで「int」に変換することができます。
1 2 3 4 5 6 |
// 下記のいずれかの方法で対応が可能です。 $fee = (int)($price * $rate_percent); $fee = (int)$fee = $price * $rate_percent; // 下記の記述では「int」にはなりません。 (int)$fee = $price * $rate_percent; |
PHPの変数の型を調べるには「gettype()」関数を使う
PHPでは変数を型を気にすることがほぼないため、そもそもの変数の確認の仕方を忘れておりまして、「in_int()」関数を使って検証を行いましたが、「gettype()」関数を使うと変数の型を簡単に確認することができます。
1 2 3 4 5 6 7 8 |
echo gettype($fee); // double echo gettype($rate_percent); // double echo gettype($fee2); // integer |
「gettype()」関数を使えばここまで悩まずに済んだかもしれません...
PHPで integerと doubleの計算をしてみて...のまとめ
PHPで integerと doubleの計算をしてみて驚きがありました!
こんな仕様、知りませんでした...
四則演算でも「+」「-」「×」は気にしなくて良さそうですが、「÷」を使うときは途中で変数を使う場合は、その変数にどのような値が入るのか、それを確認しておく必要がありますね。
ちなみに「$rate = 200」を入れると「$rate_percent」も「int」となるため、前者の計算式でも「INTです」となります。
代入される値によって結果が異なりますので、十分なデバッグが必要になりますね。
GoogleAdwords
GoogleAdwords
この記事が参考になったと思いましたらソーシャルメディアで共有していただけると嬉しいです!
関連記事
-
-
カオナビAPI Ver.2.0のtokenを取得する PHP+cURLのサンプルプログラム
PHPのcURLを使用してカオナビAPIのアクセスに必要なtoken、シートの情報を取得するサンプルプログラムを作成。cURLの処理は関数化しているため他のAPIでも流用できる。
-
-
Basic認証の.htaccess、.htpasswd生成ツールと解説
Basic認証を設定する際に必要となる.htaccess、.htpasswdファイルを生成するツール。ID、PASS、.htpasswdへのパスを入力することで編集する情報を生成します。
-
-
WindowsのXAMPPのPHPではstrptimeは使用不可。代替はdate_parse_from_formatを使う
strptimeはWindowsのPHPには未実装。LinuxとMacで挙動が異なる。PHP8.1で非推奨になる。なので日付のチェックはdate_parse_from_formatを使おう。使い方を詳細解説。
-
-
CentOS6、7のPHPを5.3から5.6、7.0、7.1にバージョンアップする手順の解説
CentOS6系、7系のPHPバージョンを5.3から5.6、7.0、7.1にアップする作業手順と解説。yum updateコマンドを使い作業時間は約10分。コマンドの解説や引数の意味なども解説しているので役に立つはず。
-
-
PHPのデバッグで使う print_r、var_dump、var_exportの動作の違い
PHPのデバッグ等で変数や配列の中身を確認するために使用する関数print_r、var_dump、var_exportの動作の違い、仕様の違いについて確認した。var_exportがオススメ。
-
-
PHPで月末から1ヶ月後「+1 month」を算出すると想定する日付にならない場合がある
PHPでは月末の1ヶ月後が想定した日付にならない場合がある。原因はバグではなくPHPの1ヶ月後の定義によるもの。なので必要とする日付を定義しそれに合わせてDateTime、modifyを使用して算出方法を解説している。
-
-
include、requireのパス指定をdirname(__FILE__)、__DIR__と書く理由
include、requireのパスの指定を dirname(__FILE__)、__DIR__で記述する理由に付いて解説。相対パス、絶対パスを直書き、パスを書かない場合は何が問題かを説明。
-
-
Smartyのテンプレート内の処理で計算、加工をする方法
Smartyのテンプレート上で変数を計算する、加工する方法を解説します。
-
-
指定した数で文字列を丸める(n文字目で…にする)関数substr、mb_substr、mb_strimwidthの違い
文字列を指定された数で抜き出すPHPの関数、substr、mb_substr、mb_strimwidthについての解説。似た関数だが引数の指定方法が違ったり、文字数がバイト数か文字数かも違ったり、注意が必要だ。
-
-
sleepの秒指定は整数のみなので1.5秒はsleep、usleepを組み合わせる
PHPのプログラム処理を遅延させる「sleep()」は整数秒単位。「usleep()」は1秒未満のマイクロ秒単位。では「1.5」秒はどう表現するのか。「sleep()」「usleep()」を組み合わせる。その解説。