PHPのPDOを使ってDBにデータを挿入しようとした際にハマりました。
bindParam()に直接値を書くをエラーになる。
データが無ければnullを入れようと思い下記の様なコードを書いていました。
<?php $stmt = $pdo->("INSERT INTO {$TABLE} (data) VALUES (:data)"); if(!empty($data)) { $stmt->bindParam(':data', $data, PDO::PARAM_STR); } else { $stmt->bindParam(':data', null, PDO::PARAM_NULL); } $stmt->execute();
データが無い時次のようなエラーになりました。。。
Fatal error: Cannot pass parameter 2 by reference
どうやらbindParam()
は第2引数に直接値を与えることができないっぽい!
一度変数に入れてあげないとダメなようです。なので下記のように書き変えればOK
<?php $stmt = $pdo->("INSERT INTO {$TABLE} (data) VALUES (:data)"); if(!empty($data)) { $stmt->bindParam(':data', $data, PDO::PARAM_STR); } else { $null = null; // 一旦変数を作る $stmt->bindParam(':data', $null, PDO::PARAM_NULL); } $stmt->execute();
何だかビミョーです...
bindValue()
を使えば直接値を渡しても問題ないようです。
↓ bindValue()
で書き換える。
<?php $stmt = $pdo->("INSERT INTO {$TABLE} (data) VALUES (:data)"); if(!empty($data)) { $stmt->bindValue(':data', $data, PDO::PARAM_STR); } else { $stmt->bindValue(':data', null, PDO::PARAM_NULL); } $stmt->execute();
bindParam()
とbindValue()
の違いは
bindParam()
は変数をバインドしexecute()
が実行された時にバインドされた変数を参照するbindValue()
は値をバインドする
という事のようです。
bindParam()
は変数をバインドした時にはexecute()
する前に同じ変数の値を変えてしまうと予期しない値がDBに渡ってしまう可能性があったり、execute()
時にINT型が文字列に変換されたりするので気をつけた方が良さそうと思いました。
- bindParam() に直接値を入れたらダメ - GR
- 最近PDOを使っていてハマったこと2つ。
- PHP、PDOの「bindValue」と「bindParam」の違い|マコトのおもちゃ箱 ~ぼへぼへ自営業者の技術メモ~
日付型(DATE, DATETIME)が存在しない?
DBの型がDATE、DATETIMEになっているカラムに値を入れようとしました。
<?php $stmt = $pdo->("INSERT INTO {$TABLE} (date, created_at) VALUES (:date, :created_at)"); $date = new Date('2014-01-18'); $stmt->bindValue(':date', $date->format('Y-m-d'), PDO::PARAM_DATE); $created_at = new Date(); $stmt->bindValue(':date', $created_at->format('Y-m-d H:i:s'), PDO::PARAM_DATETIME); $stmt->execute();
次のようなエラーが出ました。
Fatal error: Undefined class constant 'PARAM_DATE'
どうやらPDOにはPARAM_DATE
やPARAM_DATETIME
が無いっぽい。
仕方が無いので文字列PARAM_STR
でデータを挿入することにしました。。。
<?php $stmt = $pdo->("INSERT INTO {$TABLE} (date, created_at) VALUES (:date, :created_at)"); $date = new Date('2014-01-18'); $stmt->bindValue(':date', $date->format('Y-m-d'), PDO::PARAM_STR); $created_at = new Date(); $stmt->bindValue(':date', $created_at->format('Y-m-d H:i:s'), PDO::PARAM_STR); $stmt->execute();
BOOL型が上手くINSERTできない
DB作成時にis_bool BOOLEAN
で作成したカラムにPDO:: PARAM_BOOL
でデータを入れようとしてハマりました。
<?php $stmt = $pdo->("INSERT INTO {$TABLE} (is_bool) VALUES (:is_bool)"); // true $is_bool = true; $stmt->bindValue(':is_bool', $is_bool, PDO::PARAM_BOOL); $stmt->execute(); // -> false // false $is_bool = false; $stmt->bindValue(':is_bool', $is_bool, PDO::PARAM_BOOL); $stmt->execute(); // -> false
BOOL型のカラムにtrue
かfalse
でデータを入れようとしたのですが、データの挿入に失敗しているようです...
もしかしてと思いDBを見に行くと、is_bool
カラムの型がTINYINT
になっていました。
MySQLでBOOL型で作成したカラムはTINYINTになるようです。
DBの型がBOOLEANでない。もしかしてコレが原因?と思いPARAM_INT
にしてみたら上手く動作しました。
<?php $stmt = $pdo->("INSERT INTO {$TABLE} (is_bool) VALUES (:is_bool)"); // true $is_bool = true; $stmt->bindValue(':is_bool', $is_bool, PDO::PARAM_INT); $stmt->execute(); // -> true // false $is_bool = false; $stmt->bindValue(':is_bool', $is_bool, PDO::PARAM_INT); $stmt->execute(); // -> true
最近Node.jsやRubyばかり触っていてPHPを殆ど触ってなかったので色々とPHPの事を忘れてるは、色んな所にハマりまくるはで疲れきってしまいました。PHP...
本題とは関係がないのだけど、MarkdownにしたらQiitaのリンクを挿入した時に上手くタイトルが表示されないっぽい!↓
[http://qiita.com/dozen/items/e3c00a0a581378a4cc70:title]
わざわざ[タイトル](URL)
で書きなおすのめんどくさいです。。。
参考にしました