【问题标题】:PDO acts different on two -very- similar queriesPDO 对两个非常相似的查询的行为不同
【发布时间】:2009-09-17 15:48:32
【问题描述】:

以下代码块工作正常(没有错误)

$query = "select * from users where username = ?";
$statement = $sql->prepare($query);
echo gettype($statement); // -- This returns 'object'
$statement->bindParam(1, $username);

以下给出: 致命错误:在第 39 行的 /file.php 中的非对象上调用成员函数 bindParam()

$email = 'fake@email.com';
$query = "select * from users where email = ?";
$statement = $sql->prepare($query);
echo gettype($statement); // -- this returns 'boolean'
$statement->bindParam(1, $email); // -- this is line 39.

现在这很奇怪。

在我的本地机器和远程主机上,这从来都不是问题。

此错误仅出现在我本月试用的这家新托管公司上。他们编译php时会不会是配置参数?

--------编辑-------- 在试图找出问题所在的同时,我发现了这一点。

$query = "select userID, username from users";
$statement = $sql->prepare($query);    
$statement->execute();
$r = $statement->fetchAll(PDO::FETCH_ASSOC);

// display # of rows
echo "Rows returned: " . $statement->rowCount();

// display results array
echo '<pre>'; print_r($r); echo '</pre>'; 

在服务器上,我得到

Rows returned: 4

Array
(
    [0] => Array
        (
            [userID] => 1
            [username] => lyrae
        )

    [1] => Array
        (
            [userID] => 2
            [username] => jproffer
        )

    [2] => Array
        (
            [userID] => 3
            [username] => king
        )

    [3] => Array
        (
            [userID] => 4
            [username] => gergy
        )

)

这是正确的。说返回 4 行并显示结果数组。然而,在另一台服务器上,我得到了

Rows returned: 0

Array
(
    [0] => Array
        (
            [userID] => 1
            [username] => lyrae
        )

    [1] => Array
        (
            [userID] => 2
            [username] => jproffer
        )

    [2] => Array
        (
            [userID] => 3
            [username] => king
        )

    [3] => Array
        (
            [userID] => 4
            [username] => gergy
        )

)

因此,PDOStatement::rowCount() 似乎也不能在一个服务器上工作,但在另一个服务器上工作。

【问题讨论】:

  • 查询失败后有没有试过检查$sql-&gt;errorInfo()?很多时候它会直接指出问题所在。
  • 你是在 bindparam 之前还是之后调用的?

标签: php pdo


【解决方案1】:

阅读:$statement->closeCursor()

PDOStatement::closeCursor() 释放与服务器的连接,以便可以发出其他 SQL 语句

您是否在您说没有此问题的服务器上使用相同的数据库?

【讨论】:

  • 是的,我是。这是一个注册脚本,我只是查询用户名是否存在,然后我再次查询以查看“用户”表中是否存在电子邮件。
  • 而且他们都使用相同版本的PHP?所有的库都一样吗?
【解决方案2】:

找到问题的解决方案。

这是整个代码块..

// check if username exists
$query = "select * from users where username = ?";
$statement = $sql->prepare($query);
$statement->bindParam(1, $username);
$statement->execute();


// check if email exists
$sql2 = new PDO('mysql:host=localhost; dbname=db', 'username', 'pw');
$query = "select * from users";
$statement = $sql2->prepare($query);
echo gettype($statement);
#$statement->bindParam(1, $email);

所以出于某种原因,我必须创建一个新的 PDO 实例。奇怪的是,在另外 2 台服务器上,我不必这样做。

进一步查看后,我发现 PDO::Prepare 引发了 PDOExeption。

这里是:

SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute.

Array
(
    [0] => HY000
    [1] => 2014
    [2] => Cannot execute queries while other unbuffered queries are active.  Consider using PDOStatement::fetchAll().  Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute.
)

也许它会在未来帮助某人:)

【讨论】:

    【解决方案3】:

    $email 是否未定义?你也可以试试 var_dump($email) 看看它说了什么。祝你好运。

    【讨论】:

    • 即使我在块上方执行 $email = 'something',我仍然得到相同的结果。
    • 哦,再次查看错误,听起来问题一定出在 $statement 上(事实上,在生产中,它是布尔值)。如果发生错误,我认为 $sql->prepare() 返回 false,因此您可以查看。可能是数据库连接问题。
    【解决方案4】:

    您是否尝试将$email= 行放在bindParam 下方(但在执行之前)? bindParam 通过引用传递参数,因此您可以作为查询执行,更改变量的值并再次执行。

    我认为这可能是 PHP 设置错误。我听说有人说 PDO 在 PHP 5.3 之前有很多错误,所以也许看看你能不能把 PHP 升级到最新版本?

    您是否也尝试过交换这两个查询?运行一个查询后,可能会出现问题。

    【讨论】:

    • 即使我只是在页面上单独拥有电子邮件查询块,它也不起作用。因此,它与页面上其他代码的比较顺序并没有什么区别。感谢您提供有关 5.3 之前的 PDO 的信息。我正在运行 5.2.6,所以也许这就是原因。虽然我目前的主机使用的是 5.2.9,但它运行良好。我会要求他们升级到 5.3,看看会发生什么。谢谢!
    【解决方案5】:

    我最好推荐使用这个:

    $email = 'fake@email.com';
    $query = "select * from users where email = ?";
    $statement = $sql->prepare($query);
    $statement->execute(array($email));
    

    这里不需要使用 BindParam。

    【讨论】:

      【解决方案6】:

      我有同样的问题 echo "返回的行数:"。 $statement->rowCount();

      我得到了 -1 行,哈哈。我的数据库是 INFORMIX,我在网上搜索发现 那行计数();仅返回相应 PDOStatement 对象执行的 DELETE、INSERT 或 UPDATE 语句中受影响的行。

      使用 SELECT 语句需要使用函数 $statement->fetchColumn();

      在这里阅读:http://www.phpbuilder.com/manual/en/function.pdostatement-rowcount.php

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-08-02
        • 1970-01-01
        • 1970-01-01
        • 2021-11-09
        • 1970-01-01
        • 1970-01-01
        • 2011-10-25
        相关资源
        最近更新 更多