2012-03-25 26 views
2

次のコードを使用しています。コードは動作しますが、私は(私はPDOとbindParamを使ってmysqlに配列を挿入するには?

$sql = "INSERT INTO qresults (instance, qid, result) VALUES (:an_array)"; 
$stmt = $dbh->prepare($sql); 
$stmt->bindParam(':an_array', implode(',', $values),PDO::PARAM_STR); 
$stmt->execute(); 

と、次の

$count = $dbh->exec("INSERT INTO qresults(instance, qid, result) VALUES ".implode (', ', $values)); 

を交換しますが、挿入はもう動作しないことがbindparam

try { 
    $dbh = new PDO("mysql:host=$hostname;dbname=$dbname", $username, $password); 
$stqid=array(); 

    for ($i=0; $i<$array_count; $i++){ 
    $stqid[$i][0]=$lastInsertValue; 
    $stqid[$i][1]=$qid[$i][0]; 
    $stqid[$i][2]=$qid[$i][1]; 
    } 

$values = array(); 
    foreach ($stqid as $rowValues) { 
     foreach ($rowValues as $key => $rowValue) { 
     $rowValues[$key] = $rowValues[$key]; 
     } 

    $values[] = "(" . implode(', ', $rowValues) . ")"; 
    } 

$count = $dbh->exec("INSERT INTO qresults(instance, qid, result) VALUES ".implode (', ', $values)); 
$dbh = null; 
} 
catch(PDOException $e){ 
    echo $e->getMessage(); 
} 

を使用するように、それを変更したいです私はどんなエラーメッセージも得なかった)。

質問:私は間違っていますか?どうすればbindParamを使うようにコードを書き直すことができますか?

答えて

3

ステートメントを作成してparamをバインドしようとしています。

ステートメントは、あらゆる種類のSQLインジェクションを無効にする可能性があるため、優れています。それは、文字列としてしか見えないクエリの概念を取り除くことによって行います。 SQLクエリは、パラメータリストと関連データをバインドされた変数として持つ文字列として認識されます。 クエリはテキストだけでなく、テキスト+データです。

私は意味:

この単純なクエリ:

SELECT * FROM A WHERE val="$param" 

クエリが唯一の文字列として表示されるので、それは安全ではありません。 $ paramがチェックされていなければ、それはSQLiの穴です。

しかし、ステートメントを作成する場合、クエリは次のようになります。

SELECT * FROM A WHERE val=:param 

次にあなたが値を指定するbindparamを使用します。PARAMを。つまり、値はクエリ文字列に追加されませんが、クエリは既に解析されており、データが提供されています。

あなたのケースでは、あなたはparam:arrayに配列を埋め込みます(私は "data1"、 "data2"などと仮定します)。これは値を文字列( "data1、data2、data3 ...")として持つ1つのパラメータなので、挿入が1つだけで複数の挿入は行われません。

次に、あなたの配列を処理するのに十分なパラメータ

$sql = "INSERT INTO qresults (instance, qid, result) VALUES (:val0, :val1, :val2, ...)"; 

でクエリを生成することによって、あなたのアレイ上のループをあなたの文の生成を変更し、各パラメータについてbindparamメソッドを呼び出すことができます。

$count = 0; 
foreach($values as $val) 
{ 
    $stmt->bindParam(":val$count", $val,PDO::PARAM_STR); 
    $count++; 

} 

これは動作します。

編集:このソリューションは、1次元配列のためにどのように機能するかを示しているが、簡単に文のクエリの生成を微調整することで、あなたの問題に拡張し、bindparamループを変更することができます。

あなたの文のように見えるはずです:

$sql = "INSERT INTO qresults (instance, qid, result) VALUES (:val0, :val1, :val2) , (:val3, :val4, :val5), ..."; 

は、あなたは自分のベース・アレイ内の要素の数をカウントする必要があります。

+0

回答を更新していただきありがとうございます。今理解するのがはるかに簡単です:) – TryHarder

+0

挿入する値の数が毎回異なる場合、これを行う方法はありますか? – TryHarder

+0

ええ、必要に応じてクエリ文字列を生成し、生成したクエリのものと一致するパラメータをバインドするだけです – grifos

関連する問題