プログラミング言語や環境設定を中心としたパソコン関連の技術メモです。
主にシステム開発中に調べたことをメモしています。TIPS的な位置付けで、気が向いたときにちまちま更新していきます。
PHP、PDOの「bindValue」と「bindParam」の違い
結論だけ書けば

bindValue:値をバイントする
bindParam:変数をバイントする

なのですが、これで分かるならわざわざ調べたりしてないですよね。
もうちょっと細かく説明していきます。

恐らく実例を見た方が分かりやすいと思うので、
まずはこちらのサンプルをご覧くださいφ(--)

<?php

$dsn = 'mysql:dbname=fp_test;host=127.0.0.1;charset=utf8';
$user = 'user';
$pwd = 'pwd';

//DB接続
try {
    $pdo = new PDO($dsn, $user, $pwd);
} catch (PDOException $e) {
    die('DB接続失敗:' . mb_convert_encoding($e->getMessage(), 'UTF-8','SJIS-win'));
}

//------------------------
//INSERT
//------------------------
$sql = 'INSERT into tbl_test01 (column_varchar01, column_varchar02) VALUES (:column_varchar01, :column_varchar02)';
$stmt = $pdo->prepare($sql);

//bindValue
$val01 = "ほげ1";
$stmt->bindValue(':column_varchar01', $val01);
$val01 = "ほげ2";

//bindParam
$val02 = "ほげ1";
$stmt->bindParam(':column_varchar02', $val02);
$val02 = "ほげ2";

//実行
$ret = $stmt->execute();

if (!$ret) {
    die('INSERT 失敗');
}

// auto increment値取得
$id = $pdo->lastInsertId();

//------------------------
//SELECT(prepare→execute)
//------------------------
$sql = 'SELECT * FROM tbl_test01 WHERE pk_id = :id;';
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':id', $id);
$ret = $stmt->execute();
if (!$ret) {
    $err = $pdo->errorInfo();
    die('SELECT 失敗:' . mb_convert_encoding($err[2], 'UTF-8','SJIS-win'));
}

//結果取得
print "■$sql<br>\n";
$data = $stmt->fetch(PDO::FETCH_ASSOC);
print_r($data);


//さよーなら
$pdo = null;

ちなみに「fp_test」というDB(ユーザID/パスワード:user/pwd)に
 pk_id:数値型(プライマリキー)
 column_varchar01:文字列型
 column_varchar02:文字列型
のカラムを持つテーブル「tbl_test01」を用意して、それを使っています。

注目すべきポイントは

//bindValue
$val01 = "ほげ1";
$stmt->bindValue(':column_varchar01', $val01);
$val01 = "ほげ2";

//bindParam
$val02 = "ほげ1";
$stmt->bindParam(':column_varchar02', $val02);
$val02 = "ほげ2";

//実行
$ret = $stmt->execute();

の部分です。
このサンプルコードの実行結果は

■SELECT * FROM tbl_test01 WHERE pk_id = :id;
Array ( [pk_id] => 46 [column_varchar01] => ほげ1 [column_varchar02] => ほげ2 )

になります。
「:column_varchar01」には「ほげ1」が
「:column_varchar02」には「ほげ2」が設定されたわけですね。

これが「bindValue()」と「bindParam()」の違いです。

「bindValue()」は値をバインドします。
すなわち

//bindValue
$val01 = "ほげ1";
$stmt->bindValue(':column_varchar01', $val01);
$val01 = "ほげ2";



$stmt->bindValue(':column_varchar01', $val01);



$stmt->bindValue(':column_varchar01', 'ほげ1');

と書いたのと同じことなのです。
そのため「:column_varchar01」には「ほげ1」が設定されます。

これが「bindValue()」の動き(--)b

では「bindParam()」の方はどうか?
「bindParam()」でバインドするのはあくまでパラメータです。
値じゃありません。

//bindParam
$val02 = "ほげ1";
$stmt->bindParam(':column_varchar02', $val02);
$val02 = "ほげ2";



$stmt->bindParam(':column_varchar02', $val02);

は、あくまで「『$val2』って変数をバインドすっから」の意味なのです。
「$val2に何が入っているか?そんなの知らねーよ」です。

では実際に$val2の中身を参照するのはいつなのか?

それは実行時、つまり

//実行
$ret = $stmt->execute();

の時点です。
実行時点では既に

$val02 = "ほげ2";

を通っていますので「$val02」の中身は「ほげ2」になっていますよね。
そのため「:column_varchar02」には「ほげ2」が設定されるのです。

これが「bindParam()」の動き(--)b

「bindValue()」はあくまで値をバインドします。
「bindParam()」は変数をバインドします。実際に変数の中身を参照するのは「execute()」時です。
これが「bindValue()」と「bindParam()」の違いです。

どちらも使い所はあると思います。
ただ個人的には「bindValue()」を使うように意識した方が
紛れ(バグの元)は少なくなるかな~と考えています。

「bindValue」と「bindParam」の違いの理解、完了\(--)/
スポンサーリンク
 
このエントリーをはてなブックマークに追加 

category:PDO  thema:システム開発 - genre:コンピュータ  Posted by ササキマコト 

  関連記事