2016年8月11日木曜日

【※どちらかというと非推奨】fuelphpでDB::selectしたときの結果で数値型が文字列型になってしまうのを直してみた的なお話

  • このエントリーをはてなブックマークに追加

fuelphpに限らずPDOを使っていると直面する問題ではあるらしいけれど、
とりあえず結果として出てきたものが全てstringになっているっていう深刻な問題がある。
ちなみにintがstringになるだけはなく、boolすらstringになるっていう。
特にこれがやっかいになるのがrestを使ってjsonとして出した際に、hoge?"foo":"bar"みたいにjs側で処理をしたいのにできないっていう。
hoge === "1"?"foo":"bar"なんていう変な書き方をしないといけないっていう。

ってなわけで今回はこれの直し方をば。

// Force PDO to use exceptions for all errors
$this->_config['attrs'] = array(
  \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
  \PDO::ATTR_EMULATE_PREPARES => false
);

81行目あたりPDOのconfigを入れる部分があるので、ここに\PDO::ATTR_EMULATE_PREPARES => falseと入れてあげればよい。

なんていうかPDOの仕様でこうなってしまうっていうイジメな話。

特にこのご時世reactだなんだでAPIとしてjsonを出すっていうことが増えているので、余計な書き方とかはしたくないわけで。
ってことでこのことをgithubでissueとしてあげようと思ってるけど英語で書かないといけないのかってビクビクしている。

とりあえずそんな感じで解決する的なお話。

---8/12追記---
When using PDO, select result integer becomes string #2014
githubにissueを投げたところ、自分のやり方だと後方互換生を損なうだとかなんとかでダメだよっていうお話。
とりあえずそもそもdb configからpdoのattrを投げれるらしい。
なのでdb configから投げてあげればいいんだが、fuel/core/classes/database/pdo/connection.phpも若干バグがあったらしいっていう。
fixed bug that prevented configured PDO attrs from being set
1.9からはちゃんとこうなる仕様らしい。

ってなわけでfuel/core/classes/database/pdo/connection.phpはこれに書き換えて、db.phpを下記にしてみた。
return array(
  'default' => array(
    'connection'  => array(
      'dsn'        => 'hogehoge',
      'username'   => 'hogehoge',
      'password'   => 'hogehoge',
    ),
    'charset' => 'utf8',
    'attrs' => array(
      \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
      \PDO::ATTR_EMULATE_PREPARES => false
    ),
  )
);

ただATTR_EMULATE_PREPARESで調べてみるとこんなのを見つけた。
PDOでATTR_EMULATE_PREPARESを適切に設定してないとSQLインジェクションの原因になるかも(MySQL編)
確かにSQLインジェクションの対策としてプリペアドステートメントがあるわけで、これを切ってるようなものだから危ないよねとは思った。
なのでこの仕様にするのは個人サイトだったりするなりして自己責任のもと行った方がいいんじゃないかと!!

Adsense