PDOのバインドをforeachでまとめて処理したいができません

このQ&Aのポイント
  • PDOのバインドをforeachループでまとめて処理しようとしていますが、うまくいきません。
  • PHP5.2.5を使用しています。DBには'id'、'color'、'num'の3つのフィールドがあります。
  • 方法1では、foreachループでバインド処理を行っていますが、結果がうまくいかず、[color]の値が6と表示されてしまいます。方法2では手書きでバインド処理を行っているため正しく処理されます。方法1の問題箇所を教えていただきたいです。
回答を見る
  • ベストアンサー

PDOのバインドをforeachでまとめて処理したいができません…。

いつもお世話になっております。 PHP5.2.5 --------------------------- DB(フィールドは以下3項目) ・id(primary key) ・color ・num --------------------------- //DBにインサートするデータ群(配列に格納してある) $insert_array = array('color'=>'red','num'=>6); //================================================== // *フィールド名とそれに対応するデータをバインドする。 //================================================== //================================================== // *バインド:方法1 //================================================== foreach($insert_array as $field => $value){  //確認処理  //echo $field.'<br/>';  //echo $value.'<br/>';  //バインド(foreachで、1つずつバインドしていく)  $stmt->bindParam(':'.$field,$value); } //================================================== // *バインド:方法2(↓こちらだと上手くいく。) //================================================== /* $stmt->bindParam(':'.'color',$insert_array['color']); $stmt->bindParam(':'.'num',$insert_array['num']); */ //================================================== // *バインド後、「$stmt->execute();」した結果 // *DBにインサートされたものをprint_r()にて確認 //================================================== ★方法1 Array ( [id] => 15 [color] => 6 [num] => 6 ) //--------------------------- ★方法2 Array ( [id] => 16 [color] => red [num] => 6 ) //--------------------------- ★方法1の結果の、「 [color] => 6」って一体…?! 方法2のように、同じバインド処理を手書きで繰り返す分にはうまくいくのですが、 方法1のようなforeachでまとめて処理するやり方だとうまくいきません。 方法1の問題箇所をどなたか教えて下さい。 宜しくお願い致します。

  • march4
  • お礼率83% (628/754)
  • PHP
  • 回答数1
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

bindParamでバインドされるのは変数の値ではなく変数です。また、マニュアルから引用すると 「変数は参照としてバインドされ、PDOStatement::execute() がコールされたときのみ評価されます。」 なので、foreach内での >$stmt->bindParam(':'.$field,$value); は、言ってみれば$valueの位置を記憶しているにすぎません。 で、execute実行時に初めて中身の値を取りに行き、そこに入っているもの(要するにforeachの最後の値)をセットしてしまっています。

参考URL:
http://www.php.net/manual/ja/pdostatement.bindparam.php
march4
質問者

お礼

早速どうもありがとうございます。 >bindParamでバインドされるのは変数の値ではなく変数 すぱっと理解できました。 では、いざ挑戦してきます! うまく動くことが確認できましたら、回答を締め切らせて頂きます!

関連するQ&A

  • PDOについて

    プログラム初心者です 最近PDO使うようになりましたがまったく使いこなせません 何回もSQL発行して効率わるいコードになりました(--; 一回のSQL発行にまとめる方法はありますか? for ($i=0; $i<$count; $i++) { $id=$Array[$i][0]; $name=$Array[$i][1]; $stmt = $pdo -> prepare("INSERT IGNORE INTO table(id,name) VALUES (?,?)"); $stmt->bindValue(1, $id, PDO::PARAM_INT); $stmt->bindValue(2, $name, PDO::PARAM_STR); $stmt->execute(); } 質問2 prepareのキャッシュを利かすってどうゆうことでしょうか?上の場合でもキャッシュ生かせていますか? よろしくお願いします

    • ベストアンサー
    • PHP
  • PDOを使って複数キーワード検索する方法について

    PDOでプリペアードステートメントを使って複数キーワードで検索する方法を教えて下さい。 プリペアードステートメントは「?」形式ではなく、$stmt->bindParam(':sample', $samle);の形を使った方法を知りたいです。 環境 PHP:5.1.6 MySQL:5.0.77 処理の流れを作ってみました。途中から不明な点があるので変数化しないで記載してあります。 /*--PDOのプリペアードステートメントのbindParamを用いた場合--*/ $dbh = new PDO($DSN , $DBUSER , $DBPASS); $query = 'SELECT * FROM table WHERE '; $keyword_str = 'キーワードA キーワードB キーワードC'; //全角スペースを半角スペースに変換する処理(省略) $keywords = split(' ',$keyword_str); for($a = 0; $a <$keywords_num; $a++) { $kw[]=' 列名 like :kw'.$a; } $query.= join('AND', $kw); //キーワードごとに「%キーワード%」の形を作る。 $kw0='%'.$keywords[0].'%'; $kw1='%'.$keywords[1].'%'; $kw2='%'.$keywords[2].'%'; $stmt = $dbh->prepare($query); $stmt->bindParam(':kw0', $kw0); $stmt->bindParam(':kw1', $kw1); $stmt->bindParam(':kw2', $kw2); $stmt->execute(); /*-----------------------------------------------------------*/ 上記ソースの後半部分、 (1) //キーワードごとに「%キーワード%」の形を作る。 のところを変数を使って実現しようと思うのですが、うまくいきません。 $keywords_num=count($keywords); でキーワードの数を取得して for($a = 0; $a <=$keywords_num; $a++) { //作りたいソース } の形にすることは予想がつくのですが。 (2) $stmt->bindParam(':kw0', $kw0); $stmt->bindParam(':kw1', $kw1); $stmt->bindParam(':kw2', $kw2); の部分も上記と同じ形を考えていますが $keywords_num=count($keywords); でキーワードの数を取得して for($a = 0; $a <=$keywords_num; $a++) { //作りたいソース } 「//作りたいソース」の部分がうまく作れません。 (1)(2)の作りたいソース部分の書き方を教えて下さい。 上記の考え方より良い(短い)ソースが作れる場合はそのソースを教えて下さい。

    • ベストアンサー
    • PHP
  • 多次元配列で、foreachを使って、key値を

    多次元配列で、foreachを使って、key値を入れ替えているのですが、 なんで、こうなるか分かりません。  $x = array();  $x[] = array(   "id" => 1,   "name" => "JavaScript",  );  $x[] = array(   "id" => 5,   "name" => "PHP",  );  $z = array();  foreach($x as $key => $value){   $z[$value["id"]] = $value;   }  print_r($z); 配列のKEYをIDに変更しているのですが、 なんで、こうなるのでしょうか? 特に、  $z[$value["id"]] = $value; が分かりません。 例えば、foerachの途中で、var_dumpすると、 1回目だと、 ◆$key 0 ◆$value Array (  [id] => 1  [name] => JavaScript ) ◆$value["id"] 1 まではいいのですが、 ◆$z[$value["id"]] の値が見れません。 ここはどんな処理をやっているのでしょうか?

    • ベストアンサー
    • PHP
  • mysqlのデータをPDOでDELETEできない

    PDOオブジェクト(PHP)を使用したmysqlのデータ削除について、質問させてください。 PDOオブジェクトを使用して、mysqlのデータ読み込み・削除を行っています。 特定のデータを読み込み、処理を行わせた後、対象のデータの削除をしたいのですが 読み込みは出来るのに、削除で失敗してしまいます。 処理を行わせるSQLをvar_dumpで出力させ、 それを直接phpMyAdminでSQL実行してみたのですが、 問題なく削除が行われています。 SQLの問題ではなく、PHP側の問題だと思うのですが、 解決方法が見つかっておりません。 知恵を貸していただけないでしょうか。 $post_data = explode('¥t', $_POST['data_array']); $user_id = $post_data[0]; $account_name = $post_data[1]; $data_id = $post_data[2]; $gunre_id = $post_data[3]; try { // DB接続 $dbh = new PDO($serverInfo["SERVER"], $serverInfo["USER"], $serverInfo["PASS"]); $dbh -> query('SET NAMES utf8'); // 処理させる対象アカウント情報を取得 $sql_account; $sql_account = 'SELECT * FROM '. $serverInfo['TBL_ACCOUNT']. ' WHERE GUNRE_ID = :gunre'; } $stmt_account = $dbh -> prepare($sql_account); $stmt_account -> bindParam(':gunre', $gunre_id, PDO::PARAM_STR); $stmt_account -> execute(); while($account = $stmt_account -> fetch(PDO::FETCH_ASSOC)) { // 取得してきたデータを使用して処理 // この処理は正常に行われているので、SELECTは正常に行われていると考えられます } // 処理が完了したら、データを削除 // ↓ここで組み立てたSQLを出力し、phpMyAdminでSQL実行すると、データは削除されました $sql_delete = 'DELETE FROM '. $serverInfo['TBL_DATA']. ' WHERE USER_ID = "'. $user_id. '" AND ACCOUNT_NAME = "'. $account_name. '" AND DATA_ID = "'. $data_id. '"'; $stmt_delete = $dbh -> prepare($sql_delete); // ↓元々はbindParamで指定していたのですが、処理が出来なかったので // $SQL_deleteの中に値を埋め込み、処理を行わせました。結局出来なかったのですが・・・ // $stmt_delete -> bindParam(':id', $user_id, PDO::PARAM_STR); // $stmt_delete -> bindParam(':account', $account_name, PDO::PARAM_STR); // $stmt_delete -> bindParam(':data', $data_id, PDO::PARAM_STR); $result = $stmt_delete -> execute(); var_dump($result); // ←出力結果は「false」です } catch (Exception $ex) { echo '<font color="red">システムエラーが発生しました</font><br />'; exit(); } 以上、よろしくお願いします。

    • ベストアンサー
    • PHP
  • foreachで配列を作る

    $array = array("id","name","address","tel","point","a1"); $res = $db->query($sql);  //sqlのクエリー while ($row = $res->fetchRow( DB_FETCHMODE_ASSOC )) { $data_list[]=array( $array[0]=>$row["$array[0]"], $array[1]=>$row["$array[1]"], $array[2]=>$row["$array[2]"], $array[3]=>$row["$array[3]"], $array[4]=>$row["$array[4]"], $array[5]=>$row["$array[5]"]); } をforeachを使って $array = array("id","name","address","tel","point","a1"); $res = $db->query($sql);  //sqlのクエリー while ($row = $res->fetchRow( DB_FETCHMODE_ASSOC )) { foreach(~){             //処理     } のようにかきかえたいのですがどうしたらいいでしょうか?foreachをしらべていろろやったのですがうまくいきません。よろしくおねがいします。  ちなみに$data_list[]の配列はArray ( [0] => id [1] => name [2] => address [3] => tel [4] => point [5] => a1 ) Array ( [0] => Array ( [id] => 0 [name] => ここあ [address] => 東京 [tel] => 2 [point] => 2 [a1] => 2 ) [1] => Array ( [id] => 1 [name] => 太郎 [address] => 東京 [tel] => 3 [point] => 5 [a1] => あ ) [2] => Array ( [id] => 4 [name] => 五郎 [address] => 東京 [tel] => 0 [point] => 1 [a1] => あああああ ) [3] => Array ( [id] => 5 [name] => 士郎 [address] => 神奈川 [tel] => 26 [point] => 5 [a1] => ああああああああああ ) …となります。

    • 締切済み
    • PHP
  • PHPのPDOについて

    例えば手続き型でしたら、値をデータベースに追加するとき $sql = sprintf( 'INSERT INTO member SET id=%d, message="%s" ', mysql_real_escape_string($id), mysql_real_escape_string($message) ); mysql_query($sql) or die(mysql_error()); など「mysql_real_escape_string」を使って多少なりともセキュリティーをかけると思うのですが、PDOですと下記に書かれている以外に見たことないのですが、「mysql_real_escape_string」などはやらなくても大丈夫ということなのでしょうか? PDOの場合 $sql = 'INSERT INTO member SET id=?, message=?'; $stmt = $db->prepare($sql); $stmt->execute(array($id, $message)); 色々調べてみたのですがいまいち分からないためよろしくお願いします。

    • ベストアンサー
    • PHP
  • phpにてforeachで配列の値が取り出せない

    以下のコードで「print $value」が空っぽなのですが なにが間違っているのかがわかりません。 ---------------------- $a=1 $b=2 $c=3 $d=4 $num = array($a,$b,$c,$d); foreach($num as $value){ print $value; } ---------------------- 初歩的な質問で恐れ入りますが 間違っている箇所があれば指摘いただきたいです。 宜しくお願いします。

    • ベストアンサー
    • PHP
  • foreachで多次元配列にしたくないのですが……

    foreachで多次元配列にしたくないのですが、多次元配列になってしまいます。 なぜでしょうか? ■$hoge Array (  [0] => 3  [1] => 9 ) ■処理 foreach ($hoge as $val){  $result[]= 関数($val); } ■期待している結果 Array (   [0] => Array     (       [id] => 1       [created_at] => 2013-08-01     )   [1] => Array     (       [id] => 2       [created_at] => 2013-08-02     ) ) ■実際の結果 Array (   [0] => Array     (       [0] => Array          (            [id] => 1            [created_at] => 2013-08-01          )     )   [1] => Array     (       [0] => Array          (            [id] => 2            [created_at] => 2013-08-02          )     ) )

    • ベストアンサー
    • PHP
  • foreachの処理方法について

    ●やりたい事 【変更前】は抽出した顧客を一度に全て処理していた。 【変更後】は抽出した顧客を100件ごとに処理したい。 抽出後の処理をforeachでやっているので 100件処理して次の101件目からなど、どう対処してよいか わかりません。よい対処方法があれな教えてください。 ※「対象条件のデータを全件抽出する」部分は変更したくないです。 その後の処理で対応できればと考えています。 DB接続処理は省略してます。 【変更前】 //対象条件のデータを全件抽出する $sql = "select * from テーブル名"; $result=mysql_query($sql); if(!$result){ mysql_close($conn); exit; } while ($row = mysql_fetch_array($result)) { $data[] = $row; } mysql_free_result($result); foreach($data as $value){ //該当顧客を対象に処理する } 【変更後】 //対象条件のデータを全件抽出する $sql = "select * from テーブル名"; $result=mysql_query($sql); if(!$result){ mysql_close($conn); exit; } while ($row = mysql_fetch_array($result)) { $data[] = $row; } mysql_free_result($result); //ループ数の計算 $loop = ceil( count($data) / 100 ); //************************************* //ここで$dataを分割できないでしょうか? //************************************* for($i=0;i<$loop;$i++){ foreach($data as $value){ //該当100件ごと顧客を対象に処理する } }

    • ベストアンサー
    • PHP
  • 複数のforeachをまとめるには

    下記の質問と全く同じことをしたいのですが http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1332135363 回答をみても分かりませんでした。 array_mergeを使うとあったので foreach ($xmlData->Item as $itemValue) foreach ($xmlData2->Item as $itemValue2) $result = array_merge($itemValue, $itemValue2); print_r($result); としてみましたが、 Warning: array_merge() [function.array-merge]: Argument #1 is not an array とエラーが出てしまいます。 最終的には以下のようにDBに入れたいと思っているのですが その前段階としてforeachをまとめるにはどのようにしたらよいででしょうか。 $sql = "INSERT INTO teble (itemname,price) VALUES ('".$itemValue."','".$itemValue2."')";

    • ベストアンサー
    • PHP

専門家に質問してみよう