2

我很好奇我做错了什么。开始;我越来越臭名昭著

SQLSTATE[HY093]:无效的参数号:绑定变量的数量与标记的数量不匹配

现在; 我正在尝试做的事情:

  • ajax调用php脚本
  • 这个 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 回答