LoginSignup
107
108

More than 5 years have passed since last update.

bindParam()とbindValue()の違い

Last updated at Posted at 2012-12-26

変数を評価するタイミング

bind_value.php
$statement = $database->prepare('INSERT INTO favorite_category (id_users, category_id) values(:id, :category_id)');
$id = 3;
$categoryID = 10;
$statement->bindParam(':id', $id);
$statement->bindParam(':category_id', $categoryID);
$statement->execute();

$statement->bindValue(':id', 3);
$statement->bindValue(':category_id', 10);
$statement->execute();

bindParam()は変数を入れないとエラーが出る。bindValue()は値を直接入れても、変数を入れてもOK。
bindParam()はexecute()された時点で変数を評価する。bindValue()はすぐに変数を評価。

bind_param.php
$a = [
    'id' => 2,
    'user' => 'jack',
    'sex' => 1,
    'prefecture' => 24
];

$statement = $db->prepare('INSERT INTO users (id, name, sex, birthday, prefecture) VALUES (?, ?, ?, ?)');

$statement->bindParam(1, $a['id'], PDO::PARAM_STRING);
$statement->bindParam(1, $a['name'], PDO::PARAM_INT);
$statement->bindParam(2, $a['sex'], PDO::PARAM_INT);
$statement->bindParam(4, $a['prefecture'], PDO::PARAM_STRING);
$statement->execute();

bindParam()はその場では変数が評価されないので未定義の配列を指定してもエラーが出ないし、未定義のまま実行してもエラーは出ない。bindValue()だと未定義の配列を指定するとエラーが出る。

bindParam()の副作用(?)

strange_behavior.php
$statement = $database->prepare(/** 省略 **/);
$id = 3;
$statement->bindParam(':id', $id, PDO::PARAM_INT);
var_dump($id); //=> int(3);
$statement->execute();
var_dump($id); //=> string(1) "3"

bindParam()を使った場合にのみ発生する。execute()を実行したあとにbindParam()に渡した変数が文字列型になってしまう。strange_behavior.phpの場合だと, $idが整数型から文字列型に変わっている. なので, クエリを実行した後に$idを何かの処理で使用する場合, 思わぬ挙動をするおそれがある.

PDOにもそんな例があって, まさにstrange_behavior.phpbindParam()がそれにあたる. 第3引数にPDO::PARAM_INTを指定すると, バインドする変数が整数型でない場合にエラーとなってしまう. 変数$idを使って何度もクエリを実行する場合には, 結構厄介な問題になる気がする.

107
108
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
107
108