2012-01-27 8 views
6

Estoy intentando crear una biblioteca de consultas simple y estoy usando PDO para acceder a la base de datos.¿Se pueden mantener conexiones de PDO entre clases?

Digamos que tengo las dos clases siguientes:

class FirstClass { 
    var $dbh; 

    function __construct($host,$dbname,$user,$pw) { 
     $this->dbh = new PDO ("mysql:host=$host;dbname=$dbname",$user,$pw); 
    } 

    function use_second($foo) { 
     return new SecondClass ($foo,$this->dbh); 
    } 
} 

class SecondClass { 
    function __construct($foo, $dbh) { 
     $sth = $dbh->prepare('SELECT * FROM atable WHERE bar = :foo'); 
     $sth = $sth->execute(array('foo'=>$foo)); 
     // do something with the query 
    } 
} 

es esta la forma correcta de utilizar la misma conexión PDO entre las clases? - Porque me parece estar teniendo algunos problemas con esto, por ejemplo, si var_dump mi conexión de la segunda clase, me sale:

object(PDO)#2 (0) { } 

Seguramente eso no es verdad?

También si corro una consulta de selección, y luego volcar la variable $sth, acabo de llegar:

bool(true) 

Es esto porque yo estoy manejando la conexión de forma incorrecta? - Si es así, ¿cómo puedo usar correctamente la misma conexión entre las clases?

+1

Respondiendo a la pregunta del título: sí, pueden. – Tadeck

+0

Sí, porque usted puede. Podrías haber guardado el tuyo y nuestro tiempo con solo intentarlo antes de preguntar. –

+1

Um ... Mencioné en la pregunta que probé esto. Dije que no creía que funcionaba correctamente y me preguntaba si mi manejo de la conexión estaba causando –

Respuesta

3

Esto sucede, porque se sobrescribe $sth, que era su estado de cuenta, pero ahora es un valor lógico:

class SecondClass { 
    function __construct($foo, $dbh) { 
     // returns PDOStatement: 
     $sth = $dbh->prepare('SELECT * FROM atable WHERE bar = :foo'); 
     // returns boolean: 
     $sth = $sth->execute(array('foo'=>$foo)); 
     // do something with the query 
    } 
} 

para corregirlo, simplemente no sobrescribir $sth, por lo que son capaces de extraer resultados de la misma:

class SecondClass { 
    function __construct($foo, $dbh) { 
     // returns PDOStatement: 
     $sth = $dbh->prepare('SELECT * FROM atable WHERE bar = :foo'); 
     // returns boolean: 
     $success = $sth->execute(array('foo'=>$foo)); 
     // do something with the query 
     if ($success) { 
      // do something with $sth->fetchAll() or $sth->fetch(), or anything 
      $all_the_results = $sth->fetchAll(); 
     }; 
    } 
} 
+3

esta respuesta es la única que * en realidad * explica el problema - gracias –

+2

@AlexCoplan: Gracias, estoy feliz de que ayudado :) – Tadeck

0

Consulte la documentación para PDOStatement::execute. Devuelve un booleano. El hecho de que sth termina en true significa que la consulta se realizó correctamente.

Su diseño es un poco inestable porque está creando objetos en métodos no fabricados por otros objetos, lo cual puede ser confuso. Lo ideal sería que todos los objetos se crearán en el inicio de la ejecución del controlador, y se inyecta en los otros objetos que los necesitan (por ejemplo, el objeto PDO sería creada fuera de FirstClass::__construct, y usted tendría algo así como __construct(PDO $db) lugar.

0

en su caso, me gustaría simplemente pedir (al pedir que quiero decir es establecer las prequists) para el objeto PDO listo.

function __construct($dbh) { 
    $this->dbh = $dbh; 
} 

esta manera se obtiene un enfoque más limpia de lo que sus necesidades de objetos (que no necesita un usuario/contraseña, etc., ¡necesita una conexión de base de datos!)

También elimina la necesidad de la clase de abstracción (FirstClass), ya que puede ir directamente a la segunda clase.

Cuestiones relacionadas