Abstraerse de los servicios que proveen las herramientas de abstracción de acceso a Bases de Datos

Como habíamos visto en nuestro post anterior

PDO (PHP Data Objects). Capa de Abstracción de acceso a Bases de Datos utilizando el Patrón de diseño Singleton (Segunda parte)

Nuestra clase Database que usa internamente el Patrón Singleton: crea una instancia de la clase PDO a través del método getInstance(), pudiendo así invocar todos los métodos y propiedades de la misma.

¿Pero que inconveniente tendríamos si quisiéramos cambiar la Capa de Abstracción de acceso a la Bases de Datos para utilizar ADODB en vez de PDO?

Supongamos que desarrollamos todo nuestro sistema invocando las propiedades y métodos que nos provee PDO.

Inconvenientes

Estaríamos atados a una implementación concreta, con lo que rompemos con una premisa del Diseño Orientado a Objetos.

“No dependas de implementaciones concretas, solo de implementaciones abstractas”

Tendríamos que re implementar toda nuestra lógica de negocio donde quiera que hayamos utilizado una propiedad o método pertenecientes a PDO.

Solución

Adaptar la clase Database para que se abstraiga de las propiedades y métodos concretos que proveen las herramientas de Abstracción de Acceso a Bases de Datos como PDO y ADODB.

Nuestra clase Database debe contener todas las operaciones necesarias para interactuar con cualquier base de datos, pero estos métodos no estarán programados desde cero (reutilización de código), sino que reutilizan internamente algún servicio (extensión o librería) de abstracción de BD. En este caso utilizaremos PDO.


Ejemplo

database.php

  1. <?php  
  2. require_once 'web.config.php';  
  3.   
  4. /** 
  5.  * Represents a connection between PHP and a database server 
  6.  * 
  7.  */  
  8. final class Database extends PDO  
  9. {  
  10.     static private  $dns = DNS;  
  11.     static private  $username = USERNAME;  
  12.     static private  $passwd = PASSWD;  
  13.     static private  $options;  
  14.     static private  $instance;  
  15.     static private  $constructIsPrivate = true;  
  16.   
  17.     /** 
  18.      * A private constructor; prevents direct creation of object 
  19.      * 
  20.      * @access static private 
  21.      */  
  22.     public function __construct()  
  23.     {  
  24.       if (self::$constructIsPrivate) {  
  25.          trigger_error('Call to private ' . __CLASS__ .   
  26.                        '::__construct() from invalid context', E_USER_ERROR);  
  27.       }  
  28.       try {  
  29.            parent::__construct(self::$dns, self::$username, self::$passwd);  
  30.            $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);  
  31.       } catch (PDOException $e) {  
  32.            echo 'Connection failed: ' . $e->getMessage();  
  33.       }  
  34.     }  
  35.   
  36.     /** 
  37.      * Create a instance of Database class with The singleton method 
  38.      * 
  39.      * @access static public 
  40.      * @return Database object 
  41.      */  
  42.      static public function getInstance()  
  43.      {  
  44.        if (!isset(self::$instance))  
  45.        {  
  46.          self::$constructIsPrivate = false;  
  47.          $c = __CLASS__;  
  48.          self::$instance = new $c;  
  49.          self::$constructIsPrivate = true;  
  50.        }  
  51.         return self::$instance;  
  52.      }  
  53.   
  54.     /** 
  55.      * Initiates a transaction 
  56.      * 
  57.      * @access public 
  58.      * @return bool 
  59.      */  
  60.      public function beginTransaction()  
  61.      {  
  62.         return parent::beginTransaction();  
  63.      }  
  64.   
  65.     /** 
  66.      * Commits a transaction  
  67.      * 
  68.      * @access public 
  69.      * @return bool 
  70.      */  
  71.      public function commit()  
  72.      {  
  73.     return parent::commit();  
  74.      }  
  75.   
  76.     /** 
  77.      * Fetch the SQLSTATE associated with the last operation on the database handle 
  78.      * 
  79.      * @access public 
  80.      * @return string 
  81.      */  
  82.      public function errorCode()  
  83.      {  
  84.     return parent::errorCode();  
  85.      }  
  86.   
  87.     /** 
  88.      * Fetch extended error information associated with the last operation on the database handle 
  89.      * 
  90.      * @access public 
  91.      * @return array 
  92.      */  
  93.      public function errorInfo()  
  94.      {  
  95.     return parent::errorInfo();  
  96.      }  
  97.   
  98.     /** 
  99.      * Execute an SQL statement and return the number of affected rows 
  100.      * 
  101.      * @access public 
  102.      * @param  string $statement 
  103.      * @return int 
  104.      */  
  105.      public function exec($statement)  
  106.      {  
  107.     return parent::exec($statement);  
  108.      }  
  109.   
  110.     /** 
  111.      * Return an array of available PDO drivers 
  112.      * 
  113.      * @access static public 
  114.      * @return array 
  115.      */  
  116.      static public function getAvailableDrivers()  
  117.      {  
  118.     return parent::getAvailableDrivers();  
  119.      }  
  120.   
  121.     /** 
  122.      * Returns the ID of the last inserted row or sequence value  
  123.      * 
  124.      * @access public 
  125.      * @param  string[optional] $name 
  126.      * @return string 
  127.      */  
  128.      public function lastInsertId($name = null)  
  129.      {  
  130.     return parent::lastInsertId($name);  
  131.      }  
  132.   
  133.     /** 
  134.      * Prepares a statement for execution and returns a statement object 
  135.      * 
  136.      * @access public 
  137.      * @param  string $statement 
  138.      * @param  array  $driver_options 
  139.      * @return PDOStatement 
  140.      */  
  141.      public function prepare($statement$driver_options = array() )  
  142.      {  
  143.     return parent::prepare($statement$driver_options);  
  144.      }  
  145.   
  146.     /** 
  147.      * Executes an SQL statement, returning a result set as a PDOStatement object 
  148.      * 
  149.      * @access public 
  150.      * @param  string $statement 
  151.      * @return PDOStatement 
  152.      */  
  153.      public function query()  
  154.      {  
  155.         $args = func_get_args();  
  156.         switch(func_num_args()) {  
  157.             case 1:  
  158.                 return parent::query($args[0]);  
  159.                 break;  
  160.             case 2:  
  161.                 return parent::query($args[0], $args[1]);  
  162.                 break;  
  163.             case 3:  
  164.                 return parent::query($args[0], $args[1], $args[2]);  
  165.                 break;  
  166.             case 4:  
  167.                 return parent::query($args[0], $args[1], $args[2], $args[3]);  
  168.                 break;  
  169.         }  
  170.       }  
  171.   
  172.     /** 
  173.      * Quotes a string for use in a query 
  174.      * 
  175.      * @access public 
  176.      * @param  string        $string 
  177.      * @param  int[optional] $parameter_type 
  178.      * @return string 
  179.      */  
  180.      public function quote($string$parameter_type = PDO::PARAM_STR )  
  181.      {  
  182.     return parent::quote($string$parameter_type);  
  183.      }  
  184.   
  185.     /** 
  186.      * Rolls back a transaction  
  187.      * 
  188.      * @access public 
  189.      * @return bool 
  190.      */  
  191.      public function rollBack()  
  192.      {  
  193.     return parent::rollBack();  
  194.      }  
  195.   
  196.     /** 
  197.      * Set an attribute 
  198.      * 
  199.      * @access public 
  200.      * @param  int   $attribute 
  201.      * @param  mixed $value 
  202.      * @return bool 
  203.      */  
  204.      public function setAttribute($attribute$value)  
  205.      {  
  206.     return parent::setAttribute($attribute$value);  
  207.      }  
  208.   
  209.     /** 
  210.      * Bind a column to a PHP variable  
  211.      * 
  212.      * @access public 
  213.      * @param  mixed           $column 
  214.      * @param  mixed           $param 
  215.      * @param  int[optional]   $type 
  216.      * @param  int[optional]   $maxlen 
  217.      * @param  mixed[optional] $driverdata 
  218.      * @return bool 
  219.      */  
  220.      public function bindColumn($column, &$param$type = null, $maxlen = null, $driverdata = null)  
  221.      {  
  222.     return parent::bindColumn($column, &$param$type$maxlen$driverdata);  
  223.      }  
  224.   
  225.     /** 
  226.      * Binds a parameter to the specified variable name 
  227.      * 
  228.      * @access public 
  229.      * @param  mixed           $parameter  
  230.      * @param  mixed           $variable  
  231.      * @param  int[optional]   $data_type 
  232.      * @param  int[optional]   $length 
  233.      * @param  mixed[optional] $driver_options 
  234.      * @return bool 
  235.      */  
  236.      public function bindParam($parameter, &$variable$data_type = PDO::PARAM_STR, $length = null, $driver_options = null)  
  237.      {  
  238.     return parent::bindParam($parameter, &$variable$data_type$length$driver_options);  
  239.      }  
  240.   
  241.     /** 
  242.      * Binds a value to a parameter 
  243.      * 
  244.      * @access public 
  245.      * @param  mixed         $parameter 
  246.      * @param  mixed         $value 
  247.      * @param  int[optional] $data_type 
  248.      * @return bool 
  249.      */  
  250.      public function bindValue($parameter$value$data_type = PDO::PARAM_STR)  
  251.      {  
  252.     return parent::bindValue($parameter$value$data_type);  
  253.      }  
  254.   
  255.     /** 
  256.      * Closes the cursor, enabling the statement to be executed again 
  257.      * 
  258.      * @access public 
  259.      * @return bool 
  260.      */  
  261.      public function closeCursor()  
  262.      {  
  263.     return parent::closeCursor();  
  264.      }  
  265.   
  266.     /** 
  267.      * Returns the number of columns in the result set 
  268.      * 
  269.      * @access public 
  270.      * @return int 
  271.      */  
  272.      public function columnCount()  
  273.      {  
  274.     return parent::columnCount();  
  275.      }  
  276.   
  277.     /** 
  278.      * Dump a SQL prepared command 
  279.      * 
  280.      * @access public 
  281.      */  
  282.      public function debugDumpParams()  
  283.      {  
  284.     return parent::debugDumpParams();  
  285.      }  
  286.   
  287.     /** 
  288.      * Executes a prepared statement  
  289.      * 
  290.      * @access public 
  291.      * @param  array $input_parameters 
  292.      * @return bool 
  293.      */  
  294.      public function execute($input_parameters = array())  
  295.      {  
  296.     return parent::execute($input_parameters);  
  297.      }  
  298.   
  299.     /** 
  300.      * Fetches the next row from a result set 
  301.      * 
  302.      * @access public 
  303.      * @param  int[optional] $fetch_style 
  304.      * @param  int[optional] $cursor_orientation 
  305.      * @param  int[optional] $cursor_offset 
  306.      * @return mixed 
  307.      */  
  308.      public function fetch($fetch_style = PDO::FETCH_BOTH, $cursor_orientation = PDO::FETCH_ORI_NEXT, $cursor_offset = 0)  
  309.      {  
  310.     return parent::fetch($fetch_style$cursor_orientation$cursor_offset);  
  311.      }  
  312.   
  313.     /** 
  314.      * Returns an array containing all of the result set rows 
  315.      * 
  316.      * @access public 
  317.      * @param  int[optional] $fetch_style 
  318.      * @param  int[optional] $column_index 
  319.      * @param  array         $ctor_args  
  320.      * @return array 
  321.      */  
  322.      public function fetchAll($fetch_style = PDO::FETCH_BOTH, $column_index = 0 , $ctor_args = array())  
  323.      {  
  324.     return parent::fetchAll($fetch_style$column_index$ctor_args);  
  325.      }  
  326.   
  327.     /** 
  328.      * Returns a single column from the next row of a result set 
  329.      * 
  330.      * @access public 
  331.      * @param  int[optional] $column_number 
  332.      * @return string 
  333.      */  
  334.      public function fetchColumn($column_number = 0)  
  335.      {  
  336.     return parent::fetchColumn($column_number);  
  337.      }  
  338.   
  339.     /** 
  340.      * Fetches the next row and returns it as an object 
  341.      * 
  342.      * @access public 
  343.      * @param  string[optional] $class_name 
  344.      * @param  array            $ctor_args 
  345.      * @return mixed 
  346.      */  
  347.      public function fetchObject($class_name = 'stdClass'$ctor_args = null)  
  348.      {  
  349.     return parent::fetchObject($class_name$ctor_args);  
  350.      }  
  351.   
  352.     /** 
  353.      * Retrieve a attribute 
  354.      * 
  355.      * @access public 
  356.      * @param  int $attribute 
  357.      * @return mixed 
  358.      */  
  359.      public function getAttribute($attribute)  
  360.      {  
  361.     return parent::getAttribute($attribute);  
  362.      }  
  363.   
  364.     /** 
  365.      * Returns metadata for a column in a result set 
  366.      * 
  367.      * @access public 
  368.      * @param  int $column 
  369.      * @return array 
  370.      */  
  371.      public function getColumnMeta($column)  
  372.      {  
  373.     return parent::getColumnMeta($column);  
  374.      }  
  375.   
  376.     /** 
  377.      * Advances to the next rowset in a multi-rowset statement handle 
  378.      * 
  379.      * @access public 
  380.      * @return bool 
  381.      */  
  382.      public function nextRowset()  
  383.      {  
  384.     return parent::nextRowset();  
  385.      }  
  386.   
  387.     /** 
  388.      * Returns the number of rows affected by the last SQL statement 
  389.      * 
  390.      * @access public 
  391.      * @return int the number of rows.  
  392.      */  
  393.      public function rowCount()  
  394.      {  
  395.     return parent::rowCount();  
  396.      }  
  397.   
  398.     /** 
  399.      * Set the default fetch mode for this statement 
  400.      * 
  401.      * @access public 
  402.      * @param  $PDO 
  403.      * @param  object $object  
  404.      * @return bool  
  405.      */  
  406.      public function setFetchMode()  
  407.      {  
  408.         $args = func_get_args();  
  409.         switch(func_num_args()) {  
  410.             case 1:  
  411.                 return parent::setFetchMode($args[0]);  
  412.                 break;  
  413.             case 2:  
  414.                 return parent::setFetchMode($args[0], $args[1]);  
  415.                 break;  
  416.             case 3:  
  417.                 return parent::setFetchMode($args[0], $args[1], $args[2]);  
  418.                 break;  
  419.         }  
  420.      }  
  421.   
  422.     /** 
  423.      * Prevent users to clone the instance 
  424.      * 
  425.      * @access public 
  426.      * @return string trigger_error 
  427.      */  
  428.     public function __clone()  
  429.     {  
  430.         trigger_error('Clone is not allowed.', E_USER_ERROR);  
  431.     }  
  432. }  
  433. ?>  

Ventaja

Si en un futuro, encontramos otra capa de abstracción que se adapte más a nuestro contexto (rendimiento, flexibilidad, simplicidad, etc), podremos reemplazarla, sin que la lógica de nuestra aplicación se vea afectada por el cambio, (nuestra lógica depende de nuestra clase Database, y no concretamente de una capa de abstracción específica).

Artículos Relacionados

PDO (PHP Data Objects). Capa de Abstracción de acceso a Bases de Datos utilizando el Patrón de diseño Singleton (Segunda parte)

Como crear una Capa de Abstracción de acceso a Bases de Datos utilizando la extensión PDO y el Patrón de diseño Singleton.

Es decir, crearemos una clase Database que usara internamente PDO y el Patrón Singleton.







Ejemplo

Database.php

  1. <?php  
  2. require_once 'web.config.php';  
  3.   
  4. final class Database  
  5. {  
  6.   private static $dns       = DNS;  
  7.   private static $username  = USERNAME;  
  8.   private static $password  = PASSWORD;  
  9.   private static $instance;  
  10.       
  11.   private function __construct() { }  
  12.       
  13.   /** 
  14.    * Crea una instancia de la clase PDO 
  15.    *  
  16.    * @access public static 
  17.    * @return object de la clase PDO 
  18.    */  
  19.   public static function getInstance()  
  20.   {  
  21.     if (!isset(self::$instance))  
  22.     {  
  23.       self::$instance = new PDO(self::$dns, self::$username, self::$password);  
  24.       self::$instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);  
  25.     }  
  26.     return self::$instance;  
  27.   }  
  28.       
  29.       
  30.  /** 
  31.   * Impide que la clase sea clonada 
  32.   *  
  33.   * @access public 
  34.   * @return string trigger_error 
  35.   */  
  36.   public function __clone()  
  37.   {  
  38.     trigger_error('Clone is not allowed.', E_USER_ERROR);  
  39.   }  
  40. }  
  41. ?>  

web.config.php

  1. <?php  
  2. define('DNS','mysql:dbname=midbname;host=mihost');  
  3. define('USERNAME','miusername');  
  4. define('PASSWORD','mipassword');  
  5. ?>  

test.php

  1. <?php  
  2. /* 1. Conexión a la base de datos */  
  3.   
  4. require_once 'Database.php';  
  5. $dbh = Database::getInstance();  
  6.   
  7. /* Creación de la base de datos noticias */  
  8.   
  9. $dbh->query('CREATE DATABASE `noticias`  
  10.              DEFAULT CHARACTER SET  
  11.              latin1 COLLATE latin1_swedish_ci');  
  12. $dbh->query('USE `noticias`');  
  13.   
  14. /* Creación la tabla noticias */  
  15.   
  16. $dbh->query('CREATE TABLE IF NOT EXISTS `noticia` (  
  17.             `id` int(11) NOT NULL AUTO_INCREMENT,  
  18.             `titulo` varchar(50) NOT NULL,  
  19.             `texto` varchar(500) NOT NULL,  
  20.              PRIMARY KEY (`id`)  
  21.             )  
  22.             ENGINE=InnoDB  
  23.             DEFAULT CHARSET=utf8 AUTO_INCREMENT=2');  
  24.   
  25. /* Insertando datos en la tabla noticias */  
  26.   
  27. $dbh->query("INSERT INTO `noticia` (`titulo`, `texto`)  
  28.              VALUES ('PHP5 ''PHP5 y la POO.')");  
  29.   
  30. /* 2. Enviar la instrucción SQL a la base de datos */  
  31.   
  32. $resulset = $dbh->query('SELECT   `titulo`,`texto`   
  33.                          FROM     `noticia`  
  34.                          ORDER BY `titulo`');  
  35.   
  36. /* 3. Obtener y procesar los resultados */  
  37.   
  38. $noticia = $resulset->fetchObject();  
  39. echo $noticia->titulo;  
  40. echo $noticia->texto;  
  41. ?>  

Artículos relacionados

PDO (PHP Data Objects). Capa de Abstracción de acceso a Bases de Datos (Primera parte)

PDO (PHP Data Objects) es una extensión nativa de PHP5, consiste en una interface uniforme para acceder a varias bases de datos. PDO provee una capa de abstracción de acceso a bases de datos (BD), que permite al desarrollador abstraerse de la BD de una aplicación. Así, si en alguna fase de desarrollo del proyecto se necesita cambiar de BD, esto no afectaría la lógica de la aplicación.


 


Actualmente los siguientes drivers implementan la Interface PDO:

Nombre del Driver --------- Base de Datos soportadas
PDO_DBLIB ------------------ FreeTDS / Microsoft SQL Server / Sybase
PDO_FIREBIRD -------------- Firebird/Interbase 6
PDO_IBM --------------------- IBM DB2
PDO_INFORMIX ------------- IBM Informix Dynamic Server
PDO_MYSQL ----------------- MySQL 3.x/4.x/5.x
PDO_OCI ---------------------- Oracle Call Interface
PDO_ODBC ------------------- ODBC v3 (IBM DB2, unixODBC and win32 ODBC)
PDO_PGSQL ------------------ PostgreSQL
PDO_SQLITE ----------------- SQLite 3 and SQLite 2
PDO_4D ---------------------- 4D

Acceso a bases de datos en PHP5 con PDO

La extensión php_pdo para el trabajo con bases de datos esta compuesta por tres clases:

PDO: Representa una conexión entre PHP y un servidor de bases de datos.
PDOStatement: Representa una instrucción preparada y después que la instrucción es ejecutada, una result set.
PDOException: Representa un error lanzado por PDO.

La clase PDO

Sinopsis
2  PDO {
3  __construct ( string $dsn [, string $username
[, string $password [, array $driver_options ]]] )
4  bool          beginTransaction ( void )
5  bool          commit ( void )
6  mixed         errorCode ( void )
7  array         errorInfo ( void )
8  int           exec ( string $statement )
9  mixed         getAttribute ( int $attribute )
10  array        getAvailableDrivers ( void )
11  string       lastInsertId ([ string $name = NULL ] )
12  PDOStatement prepare ( string $statement 
[, array $driver_options = array() ] )
13  PDOStatement query ( string $statement )
14  string       quote ( string $string 
[, int $parameter_type = PDO::PARAM_STR ] )
15  bool         rollBack ( void )
16  bool         setAttribute ( int $attribute , mixed $value )
17  }
Métodos
  1. PDO::beginTransaction — Inicializa una transacción.
  2. PDO::commit — Commits una transacción.
  3. PDO::__construct — Crea una instancia PDO que representa una conexión a una base de datos.
  4. PDO::errorCode — Recupera el SQLSTATE asociado con la última operación en la base de datos.
  5. PDO::errorInfo — Recupera información extendida del error asociado con la ultima operación en la base de datos.
  6. PDO::exec — Ejecuta una instrucción SQL y retorna el número de filas afectadas.
  7. PDO::getAttribute — Recupera un atributo de conexión a base de dato.
  8. PDO::getAvailableDrivers — Retorna un array (arreglo) de los drivers disponibles en la extensión PDO.
  9. PDO::lastInsertId — Retorna el ID (identificador) de la última fila insertada o secuencia de valores.
  10. PDO::prepare — Prepara una instrucción para ejecución y retorna un objeto de tipo PDOStatement.
  11. PDO::query — Ejecuta una instrucción SQL, retornando un resul set como un objeto de tipo PDOStatement.
  12. PDO::quote — Quotes (Pone entre comillas simples un string) para uso en una query (consulta).
  13. PDO::rollBack — Rolls back una transacción.
  14. PDO::setAttribute — Modifica un atributo.
La clase PDOStatement

Sinopsis

2  PDOStatement implements Traversable {
3  bool    bindColumn ( mixed $column , mixed &$param 
[, int $type [, int $maxlen [, mixed $driverdata ]]] )
4  bool    bindParam ( mixed $parameter , mixed &$variable 
[, int $data_type [, int $length
[, mixed $driver_options ]]] )
5  bool    bindValue ( mixed $parameter , mixed $value 
[, int $data_type ] )
6  bool    closeCursor ( void )
7  int     columnCount ( void )
8  bool    debugDumpParams ( void )
9  string  errorCode ( void )
10 array   errorInfo ( void )
11 bool    execute ([ array $input_parameters = array() ] )
12 mixed   fetch ([ int $fetch_style = PDO::FETCH_BOTH
      [, int $cursor_orientation = PDO::FETCH_ORI_NEXT 
[, int $cursor_offset = 0 ]]] )
13 array   fetchAll ([ int $fetch_style = PDO::FETCH_BOTH 
[, int $column_index [, array $ctor_args = array() ]]] )
14  string fetchColumn ([ int $column_number = 0 ] )
15  mixed  fetchObject ([ string $class_name 
[, array $ctor_args ]] )
16  mixed  getAttribute ( int $attribute )
17  array  getColumnMeta ( int $column )
18  bool   nextRowset ( void )
19  int    rowCount ( void )
20  bool   setAttribute ( int $attribute , mixed $value )
21  bool   setFetchMode ( int $mode )
22  }
Métodos
  1. PDOStatement->bindColumn — Sustituye el valor de una columna de la base de datos a una variable PHP.
  2. PDOStatement->bindParam — Sustituye el valor de un parámetro (argumento), a el nombre de variable especificada.
  3. PDOStatement->bindValue — Sustituye un valor como parámetro.
  4. PDOStatement->closeCursor — Cierra el cursor, habilitando la instrucción a ser ejecutada otra vez.
  5. PDOStatement->columnCount — Retorna el numero de columnas en el result set.
  6. PDOStatement->debugDumpParams — Dump un commando SQL preparado.
  7. PDOStatement->errorCode — Recupera el SQLSTATE asociado con la última operación realizada en la base de datos.
  8. PDOStatement->errorInfo — Recupera información de error extendida asociada con la ultima operación realizada en la base de datos.
  9. PDOStatement->execute — Ejecuta una instrucción preparada.
  10. PDOStatement->fetch — Recupera la siguiente fila de una result set.
  11. PDOStatement->fetchAll — Retorna un array conteniendo todas las filas del resul set.
  12. PDOStatement->fetchColumn — Retorna una única columna de la siguiente fila de un result set.
  13. PDOStatement->fetchObject — Recupera la siguiente fila y la retorna como un objeto.
  14. PDOStatement->getAttribute — Recupera una atributo.
  15. PDOStatement->getColumnMeta — Retorna metadatos de una columna en un resul set.
  16. PDOStatement->nextRowset — Avanza a la siguiente Rowset en un multi-rowset.
  17. PDOStatement->rowCount — Retorna el numero de filas afectadas por la última instrucción SQL.
  18. PDOStatement->setAttribute — Modifica un atributo.
  19. PDOStatement->setFetchMode — Modifica el valor por defecto para recuperar datos de la base de datos para la instrucción actual.
Los pasos básicos para interactuar con una base de datos desde PHP son los siguientes:

1. Conectar con el servidor de bases de datos.
2. Enviar la instrucción SQL a la base de datos.
3. Obtener y procesar los resultados.

A continuación vemos los métodos concretos con los que realizaremos estas operaciones:

1. Conectar con el servidor de bases de datos (Crear el objeto PDO):

Descripción
PDO::__construct ( string $dsn [, string $username 
[, string $password [, array $driver_options ]]] )

Lista de parámetros

DNS: (Data Source Name), contiene la información requerida para conectarse a la base de datos.
username: El nombre de usuario. Este parámetro es opcional para algunos PDO drivers .
password: La contraseña. Este parámetro es opcional para algunos PDO drivers.
driver_options: Una llave=>valor del arreglo de opciones con driver de conexión especifico.

Valores retornados

En caso de éxito retorna un objeto PDO.

Errores/Excepciones

PDO::__construct() dispara un PDOException si el intento de conexión a la base de datos falla.

2. Enviar la instrucción SQL a la base de datos:

Descripción

PDOStatement PDO::query ( string $statement )

PDOStatement PDO::query ( string $statement , 
int $PDO::FETCH_COLUMN , 
int $colno )

PDOStatement PDO::query ( string $statement , 
int $PDO::FETCH_CLASS,
  string $classname ,
array $ctorargs )

PDOStatement PDO::query ( string $statement , 
int $PDO::FETCH_INTO ,
object $object )

Lista de parámetros

Instrucción SQL.

Valores retornados

PDO::query()
retorna un objeto PDOStatement.

3. Obtener y procesar los resultados.

Descripción
mixed PDOStatement::fetchObject ([ string $class_name 
[, array $ctor_args ]] )

Lista de parámetros

class_name: Nombre de la clase a crear, por defecto utiliza stdClass.
ctor_args: Elementos de este arreglo son pasados al constructor.

Valores retornados

Retorna una instancia de la clase requerida, con el nombre de las propiedades correspondiente a los nombres de las columnas o false in caso de un error.

Ejemplo completo

  1. <?php  
  2.  /* 1. Conexión a la base de datos */  
  3.   
  4.  $dsn = 'mysql:dbname=noticias;host=127.0.0.1';  
  5.  $user = 'dbuser';  
  6.  $password = 'dbpass';  
  7.  try  
  8.     {  
  9.       $dbh = new PDO($dsn$user$password);  
  10.     }  
  11.      catch (PDOException $e)  
  12.      {  
  13.        echo 'Connection failed: ' . $e->getMessage();  
  14.      }  
  15.    
  16.  /* Creación la tabla noticias */  
  17.   
  18.  $dbh->query('CREATE TABLE IF NOT EXISTS `noticia` (  
  19.              `id` int(11) NOT NULL AUTO_INCREMENT,   
  20.              `titulo` varchar(50) NOT NULL,   
  21.              `texto` varchar(500) NOT NULL,   
  22.               PRIMARY KEY (`id`)  
  23.             )   
  24.             ENGINE=InnoDB    
  25.             DEFAULT CHARSET=utf8 AUTO_INCREMENT=2');  
  26.   
  27.  /* Insertando datos en la tabla noticias */  
  28.   
  29.  $dbh->query("INSERT INTO `noticia` (`titulo`, `texto`)   
  30.               VALUES ('PHP5 ''PHP5 y la POO.')");  
  31.   
  32.  /* 2. Enviar la instrucción SQL a la base de datos */  
  33.   
  34.  $resulset = $dbh->query('SELECT   `titulo`,`texto`   
  35.                           FROM     `noticia`   
  36.                           ORDER BY `titulo`');  
  37.   
  38.  /* 3. Obtener y procesar los resultados */  
  39.   
  40.  $noticia = $resulset->fetchObject();  
  41.  echo $noticia->titulo;  
  42.  echo $noticia->texto;  
  43.  ?>  

Conclusión

PDO cumple con una premisa del diseño Orientado a Objetos:

“No dependas de implementaciones concretas, solo de implementaciones abstractas”[1]

PDO es una implementación abstracta, un paso a mejorar el performance de nuestras aplicaciones con desarrollos más portables y escalables.

Artículos relacionados
  1. PDO (PHP Data Objects). Capa de Abstracción de acceso a Bases de Datos utilizando el Patrón de diseño Singleton (Segunda parte)

Referencias Bibliográficas

[1] Enrique Place, (mayo 25, 2006). «Comentarios sobre: "¿Cual es la mejor capa de abstracción?"». Consultado el 1 de octubre del 2009.

Bibliografía


Colaboradores de Wikipedia. Capa de abstracción [en línea]. Wikipedia, La enciclopedia libre, 2009 [fecha de consulta: 17 de julio del 2009]. Disponible en <http://es.wikipedia.org/w/index.php?title=Capa_de_abstracci%C3%B3n&oldid=28148126>.