PHP5 MySql和PDO异常

6

我在使用PHP5.4和MySql的PDO时遇到了异常。

我已经阅读了几乎所有与此错误相关的帖子、博客、手册、代码片段,尝试了所有我看到的方法,但都没有成功。

因此,我希望这是由于我在特定代码中做错了什么,您可以指出来。

这是错误信息:

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.

以下是导致该错误的代码部分:

第一部分:

        $stmt = $this->dbConn->prepare("CALL getPopularProducts()");
        $stmt->execute();
        $rows = $stmt->fetchAll(\PDO::FETCH_ASSOC);

        //$stmt->closeCursor();

        foreach ($rows as $row) {
            $p = new entity\LightingPole();
             /* doing basic set stuff here so code omitted */

            // apply category to product
            $categroyTranslator = new ProductCategoryTranslator();
            $categroyTranslator->applyProductCategory($p);

第二部分:

        public function applyProductCategory(entity\Product $product) {
            $productId = $product->getProductId();
            try {
               /** exception thrown on this line **/
               $stmt = $this->dbConn->prepare("CALL getCategoryByProductId(?)"); 

               $stmt->bindParam(1, $productId, \PDO::PARAM_INT);
               $stmt->execute();

               while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)){
                   $category = new entity\ProductCategory();

                   $product->setCategory($category);
               }  
             }
             catch (\PDOException $e) {
                 echo $e->getMessage();
                 print($e->getTraceAsString());
             }
         }

这是我的数据库类:

namespace lib\database;

class Database
{
    protected static $instance;

    public static function getInstance()
    {
        if(self::$instance == null)
        {
            $dsn = "mydsn";
            $user = "myuser";
            $password = "mypassword";
            self::$instance->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);
            self::$instance->setAttribute(\PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
            self::$instance->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
        }
        return self::$instance;
    }

    private function __construct() {}

    private function __clone() {}
}

你可能会注意到我有一个调用 $stmt->closeCursor() 的注释。当我包含这行代码时,我会得到以下错误:

SQLSTATE[HY000]:General error: 2006 MySQL server has gone away

现在以功能术语来解释,我基本上正在获取流行产品列表,循环浏览它们并获取所有相关产品数据,例如ProductCategory等...
所以,这个错误仅发生在循环中的第一个产品上,即第二次调用 applyProductCategory()时完全没有问题。另一件事是,在 applyProductCategory 下面有大约4个以上的调用来检索其他类型的关联数据,而在执行此操作时从未抛出任何错误。
因此,最终,除了第一个产品没有与之关联的ProductCategory之外,其余所有热门产品都很好。
期待找出我错过了什么。希望你能指点我正确的方向。

1
@Erik,我没有逃避PDO,我正在使用PHP命名空间,斜杠是必需的,这样PHP就不会在我的类中寻找PDO。 - samazi
太酷了!每天都能学到新东西 :) - Erik
1个回答

2
尝试在抛出错误的位置之前使用 unset($stmt)。
    unset($stmt);
    $stmt = $this->dbConn->prepare("CALL getCategoryByProductId(?)");  

我之前遇到过同样的错误,不知为何这个方法解决了它。我之前在这里找到了答案:PDO非缓存查询


请注意,我将unset($stmt)放在$rows = fetchAll()之后,因为错误是在一个单独的类中抛出的,所以此时$stmt处于新的作用域。 - samazi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接