2

私は何が間違っているのか興味があります。はじめに; 私は悪名高い取得しています

SQLSTATE[HY093]: パラメーター番号が無効です: バインドされた変数の数がトークンの数と一致しません

今; 私がやろうとしていること:

  • PHPスクリプトへのajax呼び出し
  • この PHP スクリプトは $_REQUEST 配列をループし、データベースで更新する必要があるすべての値を収集します
  • 更新クエリを動的に生成し、関数に渡します

クエリを関数に渡すまで、すべてが正常に機能しているようです。関数は次のとおりです。

function modifyRecord()
    {
        global $db;
        $parameters = func_get_args();
        $query = array_shift($parameters);
        $statement = $db->prepare($query);
        try
        {
            $statement->execute($parameters);
        }
        catch (PDOException $error)
        {
            echo $error -> getMessage();
        }

    }

これによりエラーメッセージが生成されるため、$parameters の内容を確認してみました。

"UPDATE applications SET service=?,acronym=?,email=? WHERE id=2"

また、$query についても:

"value1","value2","value3"

私が見落としているものはありますか?出力を正しく読んでいる場合、3つの変数をバインドして3つの値を提供しようとしていますが、明らかにPDOの考え方は異なります:)

ご意見をお寄せいただきありがとうございます。ばかげたものになると思います...

4

3 に答える 3

0

func_get_args()コメントから、クエリとパラメーターの 2 つの文字列を含む配列が得られるように見えます。

順序が間違っている場合は、array_pop代わりにを使用する必要がありますarray_shift

さらに、パラメーター文字列を配列に変換する必要があり、個々のパラメーターを囲む引用符を取り除く必要があります。それは次のようになります (配列のクエリをポップした後):

// written out for clarity

// $parameters is still a array containing one element, the string with the parameters
$params = array_pop($parameters);

// make an array containing 3 elements from the string
$params_array = explode(',', $params);

// get rid of the quotes
foreach ($params_array as $key => $value)
{
  $params_array[$key] = trim($value, '"');
}

try
{
    $statement->execute($params_array);
}
catch (PDOException $error)
{
    echo $error -> getMessage();
}
于 2013-06-19T22:42:48.707 に答える
0

現在何が起こっているか (単なる分析):

function modifyRecord()
{
    global $db;
    $parameters = func_get_args();

    // in this point you say that $paremeters is 
    // [0]=> string(62) "UPDATE applications SET service=?,acronym=?,email=? WHERE id=2" 
    // [1]=> string(42) ""value1","value2","value3""

    // then you are doing this:
    $query = array_shift($parameters);

   // now with this array_shift you are giving the value
   // "UPDATE applications SET service=?,acronym=?,email=? WHERE id=2"
   // to the variable $query and the $parameters array has now only 1 element
   // the $parameters[0] which has the value
   // ""value1","value2","value3""
   // NOTE THE VALUE IS IN $parameters[0] which is the only element left after the array_shift


    $statement = $db->prepare($query); // here you are preparing the query, ok 
    try
    {
        $statement->execute($parameters); // here is the fault. execute expects an array with 3 elements like this:
        // $parameters[0] = "value1";
        // $parameters[1] = "value2";
        // $parameters[2] = "value3";

        // but instead execute gets this:
        // $parameters[0] = ""value1","value2","value3"";
        // so he says: i was expecting an array with 3 elements and all i got was an array which had only one element that had a string value.
        // SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens

    }
    catch (PDOException $error)
    {
        echo $error -> getMessage();
    }

}

解決策は、$parameters[0] の文字列を分解することです。注:「」は値の一部です。それらを取り除く必要があります。したがって、正しいものは次のようになります。

必要な変更 (解決策):

function modifyRecord()
{
    global $db;
    $parameters = func_get_args();

    // in this point you say that $paremeters is 
    // [0]=> string(62) "UPDATE applications SET service=?,acronym=?,email=? WHERE id=2" 
    // [1]=> string(42) ""value1","value2","value3""

    // then you are doing this:
    $query = array_shift($parameters);

   // now with this array_shift you are giving the value
   // "UPDATE applications SET service=?,acronym=?,email=? WHERE id=2"
   // to the variable $query and the $parameters array has now only 1 element
   // the $parameters[0] which has the value
   // ""value1","value2","value3""
   // NOTE THE VALUE IS IN $parameters[0] which is the only element left after the array_shift


   // lets create the $parameter_array from the $parameters[0]
   $parameter_array = explode(",",$parameters[0]);
   // and lets remove the " from the begin and the end of every element
   foreach ($parameter_array as $key => $a_parameter)
   {
       $parameter_array[$key] = trim($a_parameter, '"');
   }

    $statement = $db->prepare($query); // here you are preparing the query, ok 
    try
    {
        $statement->execute($parameter_array); // NOW its correct. we give execute what it wants: an array with 3 elements like this:
        // $parameter_array[0] = "value1";
        // $parameter_array[1] = "value2";
        // $parameter_array[2] = "value3";

    }
    catch (PDOException $error)
    {
        echo $error -> getMessage();
    }

}

ここで働いていますhttp://3v4l.org/kQsAV

于 2013-06-20T10:12:37.577 に答える
-3

今; 私がやろうとしていること:

ご存じのように、質問の仕方がひどいです。話をしないでください。コードを投稿してください。
「phpスクリプトループ」と「動的生成」の意味を実際に知っている人は誰もいません。

なぜ誰もが頭を悩ませて推測させるのですか?実行したコードそのものを投稿しないのはなぜですか?

しかし、まあ、あなたの質問を「何が問題なのか」ではなく、「どうすればいいのか」と仮定してください。別のメソッドを作成する

function runQueryArray($query,$parameters)
{
    global $db;
    $statement = $db->prepare($query);
    return $statement->execute($parameters);
}

このような場合には、この関数が必要です-明示的に渡されたパラメーターの代わりにパラメーターを持つ配列がある場合。

そして、善のために、他の回答からのこれらの爆発ベースの「ソリューション」を使用しないでください。

于 2013-06-20T10:51:36.963 に答える