2012-09-25 29 views
6

Me encontré con una excepción al usar PDO con PHP5.4 y MySql.PHP5 Excepción de MySql y PDO

He leído casi cualquier otra publicación, blog, manual, fragmento, todo lo relacionado con este error y he intentado todo lo que he visto sin suerte.

Así que espero que sea específico para algo que he hecho mal en mi código particular y me lo puede señalar.

Aquí está el error:

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.

Estas son las partes del código que conducen a este error:

Primera Parte:

 $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); 

Segunda parte:

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

Aquí es mi clase de base de datos:

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

Usted puede notar que tengo una llamada a $stmt->closeCursor() que he comentado. Cuando incluyo esta línea de código me sale el siguiente error:

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

Ahora explicarlo en términos de funcionalidad de fricción, lo que básicamente estoy haciendo aquí es obtener una lista de productos populares, de enlace a través de ellos y conseguir todo el datos de productos asociados como ProductCategory etc ...

Por lo tanto, este error ocurre solo en el primer producto del ciclo, es decir, la segunda vez que llamo a applyProductCategory() funciona bien, no hay problema. La otra cosa es que por debajo de applyProductCategory hay alrededor de 4 llamadas más para recuperar otros tipos de datos asociados y nunca se producen errores al hacer eso tampoco.

Al final, todos mis productos populares están bien, excepto que el primer producto nunca tiene una categoría de producto asociada.

Estamos ansiosos por descubrir lo que me he perdido en el camino para causar esto. Espero que puedas señalarme en las direcciones correctas.

+0

¿Por qué te escapas 'PDO'? – Erik

+1

@Erik, no estoy escapando PDO Estoy usando espacios de nombres php y la barra inclinada es necesaria para que php no busque PDO en mi clase. – samazi

+0

¡Genial! Aprendes algo nuevo todos los días :) – Erik

Respuesta

2

Tratando usando unset ($ stmt) justo antes de donde se está lanzando el error

unset($stmt); 
    $stmt = $this->dbConn->prepare("CALL getCategoryByProductId(?)"); 

me encontré con el mismo error antes y que fijo que por alguna razón. Encontré la respuesta aquí anteriormente PDO Unbuffered queries

+0

Muchas gracias, esto funcionó como un amuleto. – samazi

+0

Solo para observar, pongo el unset ($ stmt) directamente después de $ rows = fetchAll() porque el error se genera en una clase separada, por lo que $ stmt está en un nuevo ámbito en ese punto. – samazi

+0

Gotcha. Eso tiene sentido. Me alegro de que funcionó. – FajitaNachos