【MySQL】PDOで数値を取ってきても、全部文字列になる件

プログラミング

どうも、コウイチです。

 

今回は、PHPでPDOを使用して、テーブルからint型の値を取り出してくるサンプルを見てみます。

これが、なかなか挙動が変だったのです。

 

次のコードを見てください。

サンプルコード

<?php

// DB接続
$dsn = 'mysql:dbname=programming_blog;host=localhost';
$dbh = new PDO($dsn, 'root', 'pass');
$dbh->query('SET NAMES utf8');

// SQL準備
$sql = <<< SQL
SELECT suuji FROM pdo_string;
SQL;

$stmt = $dbh->prepare($sql);

// SQL実行
$stmt->execute();

$rec = $stmt->fetch(PDO::FETCH_ASSOC);

if($rec['suuji'] === 3){
	print $rec['suuji'] . 'は3です。';
}else{
	print $rec['suuji'] . 'は3ではありません。';
}

?>

pdo_stringテーブルのsuujiというカラム(int型)に、3という数値がひとつだけ入っています。

この3をPDOで取り出しているのですが

 

実行結果:3は3ではありません。

 

という結果に。

 

いや明らかに3だろうがあwww

と、格闘しておりました。

 

どうやらPDOでテーブルから取り出した値は、全部文字列になるようですね。

 

だから 文字列 === 数値 の比較でfalseになるわけです。

 

この場合ですが、3を文字列として囲み、

if($rec[‘suuji’] === ‘3’){

とすれば正常に判定できます。

PDOのプリペアドステートメントエミュレートモードが原因らしい

それでは、何が原因なんでしょうか?

なんでPHPはMySQLからのリザルトがint型のはずなのにstring型になってしまうん?

こちらのサイトによると、PDOはデフォルトでプリペアドステートメントエミュレートモードになっているらしく、それが原因でこういった現象が起こるとのこと。

 

ただし、僕はこの挙動が分かってPHP側で対策してしまったので、深くは調査していません。

 

興味があれば調べてみてください。

 

ちなみに、バインドパラメータについても、文字列として扱われるようです。

PHP: PDOStatement::execute – Manual

実行される SQL 文の中のバインドパラメータと同数の要素からなる、 値の配列。すべての値は PDO::PARAM_STR として扱われます。

こちらも注意が必要ですね。

まとめ

デフォルトでこうなっている可能性が高いのに、意外とあまり騒がれていないものなんですね。

でも思わぬバグに繋がりかねません。頭の隅に入れておきましょう。

 

ではまた。

コメント