PHP PDO 准备语句查询不更新记录

发布于 2024-08-19 15:17:08 字数 3219 浏览 6 评论 0原文

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

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

类函数:

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
)

I am having a problem using PHP's PDO object to prepare an update statement and updating the record. I have taken the raw SQL query and ran it in phpMyAdmin with the params replaced by their values that are passed to the function. Which updates the record as intended. However, when ran from the script it does not update. It throws zero errors and it returns an errorInfo() reply of 00000, which to my understanding is PDO's way of saying all is well. I know the PDO object works because it successfully inserts and selects records from the database, including the one I am trying to update. I understand this update function is ugly, I am just learning PDO.

Obviously, this is coded in PHP5, using PDO.

Class Function:

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();
    }

Called from session update/login script:

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

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

Output from echos and print_r in class function and caller:

// 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
)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

草莓酥 2024-08-26 15:17:08

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

根据 文档,您应该能够在 $stmt->queryString 中看到生成的查询进入 SQL。现在无法看到,因为您在输出 $stmt 之后将参数绑定到语句。

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

I don't know much about PDO, but my feeling is there is something wrong with the way you bind the parameters. However, the easiest way to tell for sure is to see the actual query.

According to the docs, you should be able to see the generated query as it went to SQL in $stmt->queryString. It's not possible to see right now because you are binding the parameters to the statement after you are outputting $stmt.

Do a print_r() after you bind the parameters (or maybe even after execution of the query, I don't know). You should get the real query string, and get to the bottom of the problem.

罗罗贝儿 2024-08-26 15:17:08

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

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();
    }

Corrected class function that works... Placed here in case someone would like it, to learn from, to use or what ever.

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();
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文