【问题标题】:PHP PDO Prepared statement query not updating recordPHP PDO 准备好的语句查询不更新记录
【发布时间】:2011-01-08 14:51:47
【问题描述】:

我在使用 PHP 的 PDO 对象准备更新语句和更新记录时遇到问题。我已经获取了原始 SQL 查询并在 phpMyAdmin 中运行它,参数替换为传递给函数的值。这会按预期更新记录。但是,当从脚本运行时,它不会更新。它抛出零错误并返回 00000 的 errorInfo() 回复,据我了解,这是 PDO 表示一切正常的方式。我知道 PDO 对象有效,因为它成功地插入并从数据库中选择记录,包括我要更新的记录。我知道这个更新功能很丑,我只是在学习PDO。

显然,这是用 PHP5 编码的,使用 PDO。

类函数:

public function update($tbl_name, $where = null, $what = null)
    {
        if(is_array($where))
        {
            $where_str = 'where ';
            foreach($where as $key => $val)
            {
                $where_str .= "{$key} = ':{$key}' and ";
            }
            $where_str = substr($where_str,0,-5);

            $what_str = 'set ';
            foreach($what as $key => $val)
            {
                $what_str .= "`{$key}` = ':{$key}', ";
            }
            $what_str = substr($what_str,0,-2);

            $query_str = "update {$tbl_name} {$what_str} {$where_str} LIMIT 1;";
            $stmt = $this->dbh->prepare($query_str);
            echo '<pre>'.print_r($stmt, true).'</pre>';
            foreach($what as $key => $val)
            {
                if('date_time' === $key) continue;
                $bind = $stmt->bindValue(":{$key}",$val);
                echo ($bind ? 'true' : 'false')." :{$key}=",$val,'<br/>';
            }
            foreach($where as $key => $val)
            {
                if('date_time' === $key) continue;
                $bind = $stmt->bindValue(":{$key}",$val);
                echo ($bind ? 'true' : 'false')." :{$key} ",$val,'<br/>';
            }
        }else{
            return false;
        }
        $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $exec = $stmt->execute();
        echo 'exec: '.($exec === true ? 'true:' : 'false:').':'.$exec.'<br/>';

        echo '<pre>';
        $stmt->debugDumpParams();
        echo '</pre>';

        return $stmt->errorInfo();
    }

从会话更新/登录脚本调用:

$where = array(
    'id' => $user['id'],
    );
$what = array(
    'twitter_key'    => $oauth_token,
    'twitter_secret' => $oauth_token_secret
    );

$update = $db->update('users', $where, $what);

类函数和调用者中的 echos 和 print_r 的输出:

// print_r($stmt = $this->dbh->prepare($query_str)) output:
PDOStatement Object
(
    [queryString] => update users set `twitter_key` = ':twitter_key', `twitter_secret`     = ':twitter_secret' where id = ':id' LIMIT 1;
)

// output from the bing params and execution returns
true :twitter_key=XXXXXXXXXXXXXXXXXXXXXXXXXXXX
true :twitter_secret=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
true :id 20
exec: true:1

// $stmt->debugDumpParams() output: 
SQL: [111] update users set `twitter_key` = ':twitter_key', `twitter_secret` = ':twitter_secret' where id = ':id' LIMIT 1;
Params:  3
Key: Name: [12] :twitter_key
paramno=-1
name=[12] ":twitter_key"
is_param=1
param_type=2
Key: Name: [15] :twitter_secret
paramno=-1
name=[15] ":twitter_secret"
is_param=1
param_type=2
Key: Name: [3] :id
paramno=-1
name=[3] ":id"
is_param=1
param_type=2

// print_r($stmt->errorInfo()) output:
Array
(
    [0] => 00000
)

【问题讨论】:

    标签: php pdo prepared-statement


    【解决方案1】:

    我对PDO了解不多,但我的感觉是你绑定参数的方式有问题。但是,最简单的确定方法是查看实际查询。

    根据docs,您应该能够看到生成的查询,因为它转到$stmt-&gt;queryString 中的SQL。现在看不到,因为您将参数绑定到语句之后,您正在输出$stmt

    在绑定参数之后执行print_r()(或者甚至在执行查询之后,我不知道)。你应该得到真正的查询字符串,并找到问题的根源。

    【讨论】:

    • 我在原始问题中包含了查询字符串。 [queryString] => 更新用户集twitter_key = ':twitter_key', twitter_secret = ':twitter_secret' where id = ':id' LIMIT 1;但是,为了 100%,我们得到了最终的 queryString,我可以看到我按照您的说明进行操作,结果返回相同的字符串: queryString: update users set twitter_key = ':twitter_key', twitter_secret = ':twitter_secret ' 其中 id = ':id' LIMIT 1;这也与 $stmt->debugDumpParams() 的返回匹配
    • 不,那是未处理的查询,不是吗?您实际上没有将值:twitter_key 发送到数据库?那没有意义,不是吗?
    • 那是正确的,它做了一些魔术并将 :twitter_key 更改为值。我不知道如何让它打印带有传递值的查询,或者即使它实际上是可能的。
    • 但是,我在 print_r($stmt->queryString) 执行后执行了它,它也显示了占位符
    • 这可能是您的问题所在。我认为 :xyz 值不应该用引号引起来。如果是的话,也许它不会被替换。你能去掉那些引号吗?你在哪里说$what_str.=....
    【解决方案2】:

    更正了有效的类函数...放置在这里以防有人喜欢它、学习、使用或其他任何东西。

    public function update($tbl_name, $where = null, $what = null)
        {
            if(is_array($where) && is_array($what))
            {
                $where_str = 'where ';
                foreach($where as $key => $val)
                {
                    $where_str .= "{$key} = :{$key} and ";
                }
                $where_str = substr($where_str,0,-5);
    
                $what_str = 'set ';
                foreach($what as $key => $val)
                {
                    $what_str .= "{$key} = :{$key}, ";
                }
                $what_str = substr($what_str,0,-2);
    
                $query_str = "update {$tbl_name} {$what_str} {$where_str} LIMIT 1;";
                $stmt = $this->dbh->prepare($query_str);
                foreach($what as $key => $val)
                {
                    if('date_time' === $key) continue;
                    $bind = $stmt->bindValue(":{$key}",$val);
                }
                foreach($where as $key => $val)
                {
                    if('date_time' === $key) continue;
                    if('id' === $key)
                    {
                        $bind = $stmt->bindValue(":{$key}",$val, PDO::PARAM_INT);
                    }else{
                        $bind = $stmt->bindValue(":{$key}",$val);
                    }
                }
            }else{
                return false;
            }
            $stmt->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            $exec = $stmt->execute();
            return $stmt->errorInfo();
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-01
      • 2014-08-04
      • 2011-06-21
      • 1970-01-01
      • 2010-11-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多