准备好的PDO(MySQL)更新声明

时间:2013-06-19 21:46:42

标签: php pdo

我很好奇我做错了什么。开始;我得到了臭名昭着的

  

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的想法不同:)

提前感谢任何意见 - 我相信这会是一件愚蠢的事情......

3 个答案:

答案 0 :(得分: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();
}

答案 1 :(得分: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

答案 2 :(得分:-3)

  

现在;我正在努力做的事情:

你知道,这是提问的可怕方式。不要讲故事。发布代码
实际上没有人知道“php脚本循环”和“动态生成”是什么意思。

为什么要让每个人都低头思考?为什么不发布你运行的代码?

但是,假设你的问题不是“什么错”,而是“如何做”。创建另一种方法

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

对于这种情况你需要这个函数 - 当你有一个带参数而不是显式传递参数的数组时。

为了善良,从其他答案中使用这些基于爆炸的“解决方案”。