2011-06-09 32 views
5

Soy muy nuevo en PHP con estilo OOP, y estoy tratando de implementar PDO también. Encontré esta clase pequeña y agradable en línea que maneja la conexión de la base de datos, sin embargo, no tengo idea de cómo acceder a ella desde otra clase. Aquí está el código:Pregunta de la clase PHP y PDO

class PDO_DBConnect { 
    static $db ; 
    private $dbh ; 
    private function PDO_DBConnect() { 
     $db_type = 'mysql'; //ex) mysql, postgresql, oracle 
     $db_name = 'postGal'; 
     $user = 'user' ; 
     $password = 'pass' ; 
     $host = 'localhost' ; 
     try { 
      $dsn = "$db_type:host=$host;dbname=$db_name"; 
      $this->dbh = new PDO ($dsn, $user, $password); 
      $this->dbh->setAttribute(PDO::ATTR_PERSISTENT, true); 
      $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
     } catch (PDOException $e) { 
      print "Error!: " . $e->getMessage() . "\n" ; 
      die() ; 
     } 
    } 

    public static function getInstance () { 
     if (! isset (PDO_DBConnect::$db)) { 
      PDO_DBConnect::$db = new PDO_DBConnect () ; 
     } 
     return PDO_DBConnect::$db->dbh; 
    } 
    } 

    $db_handle = PDO_DBConnect::getInstance(); 

    class Person 
    { 
    function __construct() 
    { 
     $STMT = $db_handle->prepare("SELECT title FROM posts WHERE id = ? AND author = ? LIMIT 20"); 
     $STMT->execute(array('24', 'Michael')); 

     while ($result = $STMT->fetchObject()) 
     { 
     echo $result->title; 
     echo "<br />"; 
     } 
    } 
    } 

¿Cómo puedo acceder a la variable $db_handle interior de mi clase de persona? ¿Tengo que crear una instancia de la variable dentro de la clase Person? Si es así, ¿significa eso que siempre tendré que llamarlo como $this->db_handle? Esperaba evitar eso. (Todavía sólo tienen un conocimiento muy básico de alcance variable, con clases)

+0

¿Por qué usa construcciones OO de PHP5, pero el constructor del mismo nombre de la era PHP4 es el constructor? Por favor considere cambiar a '__construct' en su lugar. – Charles

+0

No creo que haya escrito la clase PDO_DBConnect, ya que mencionó que "la encontró". – Problematic

Respuesta

5

Hay (al menos) tres formas de manejar esto. La más portátil, y frecuentemente recomendada se llama "inyección de dependencia", mediante la cual pasa el manejador de la base de datos a su clase a través de su __construct() y la almacena en una variable de clase. Requiere acceder a él con $this->db como si no quisiera tener que hacer.

class Person { 
    // Member to hold the db handle 
    public $db; 

    public function __construct($db_handle) { 
    // Assign the handle to a class member variable in the constructor 
    $this->db = $db_handle; 
    } 
    public function otherFunc() { 
    $this->db; // do something 
    } 
} 

$person = new Person($db_handle); 

método siguiente sería crear una instancia del $db_handle dentro del constructor en lugar de pasarla. Esto es un poco más difícil de probar y depurar.

class Person { 
    public $db; 
    public function __construct() { 
     $this->db = PDO_DBConnect::getInstance(); 
    } 
} 

Por último, puede llamar $db_handle como global cada vez que lo utilice en su clase. Este es quizás el más difícil de leer y depurar.

class Person { 
    public function __construct() { 
    global $db_handle; 
    } 
    public function otherFunc() { 
    global $db_handle; 
    $db_handle; // do something 
    } 
} 
+0

Muchas gracias por profundizar en esto. Era exactamente lo que necesitaba saber. Creo que el método de construcción tiene más sentido para lo que quiero usar. ¡Gracias! –

+0

Realmente confunde lo que se llama y cuándo porque la clase tiene el mismo nombre que una función dentro de ella. ¿Esto logra algo? –

+0

@Eujung Kim ¿Qué clase tiene el mismo nombre que una función dentro de ella? –

3

que puedes usar Dependency Injection:

$steve = new Person($db_handle); 

Y sí, utilizando la sintaxis que es la esperanza de evitar es la manera de hacerlo. Siempre puede asignar la variable de clase a un método local uno diciendo $dbh = $this->db_handle; que creo que es marginalmente más rápido.

3

Si realmente debe hacer el trabajo de base de datos desde el interior de su objeto Person (separation of concerns dice que esto debería tenerse cuidado de otra parte), puede pasarlo como argumento del constructor (basado en su uso, parece que esa puede ser la forma en que quieres ir), o como una inyección setter. En el primer caso:

class Person 
{ 
    function __construct($db_handle) 
    { 
     // ... your existing code 

Entonces instancia su objeto persona así:

$person = new Person($db_handle); 

Esa es realmente la única manera en que puede evitar la necesidad de usar $this->db_handler sin copiar la variable en ámbito local.