Database Wrapper para PDO +(comentario sobre performance)

  • 1 Respuestas
  • 102 Vistas
Database Wrapper para PDO +(comentario sobre performance)
« en: Junio 05, 2017, 23:45:49 pm »
Os traigo un Wrapper que uso habitualmente en mis proyectos PHP. Lo suelo tener integrado en mi skeleto Slim 3 pero lo ho usado con anterioridad en otros tipos de proyectos. Seria un sustituto del ORM que nunca me ha gustado usar. Lo he ido programando con el tiempo y las funciones insert, update y delete las cogi de algun otro Wrapper, ORM o a saber.

En mis proyectos es importante que el acceso a la base de datos sea rapido y muchas veces el uso de un ORM como Doctrine o Eloquent no son para nada rapidos:

Citar
With pure PDO:
memory: 0.0044288635253906
seconds: 0.24748301506042

With DBAL and autoload:
memory: 0.97610473632812
seconds: 0.29042816162109

Extraido de Reddit y de https://gonzalo123.com/2011/07/11/database-abstraction-layers-in-php-pdo-versus-dbal/


No es el codigo mas elegante ni de la ultima version de PHP, de hecho tengo que actualizarlo para poder usar toda la potencia de PDO, aun asi, aqui os lo pego y luego un tutorial de como usarlo (os prometo que lo actualizare para sacarle mas jugo):
Código: PHP
  1. class DatabaseWrapper {
  2.  
  3.     private $_conn;
  4.  
  5.     public function __construct( $db )
  6.     {
  7.  
  8.         $pdo                = new PDO($db['conn'], $db['user'], $db['pass'], $db['options']);
  9.  
  10.         $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  11.         $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
  12.  
  13.         $this->_conn        = $pdo;
  14.  
  15.     }
  16.  
  17.     protected function exec($query, $params)
  18.     {
  19.  
  20.         if (strpos($query,'SELECT') !== false) {
  21.             return $this->executeQuery($query, $params)->fetchAll(\PDO::FETCH_ASSOC);
  22.         }
  23.  
  24.         return $this->executeQuery($query, $params)->rowCount();
  25.  
  26.     }
  27.  
  28.     protected function executeQuery($query, $params) {
  29.  
  30.         $statment   = $this->_conn->prepare($query);
  31.         $statment->execute($params);
  32.  
  33.         return $statment;
  34.  
  35.     }
  36.  
  37.     public function fetchRow($query, $params = array()) {
  38.  
  39.         return $this->executeQuery($query,$params)->fetch(\PDO::FETCH_ASSOC);
  40.  
  41.     }
  42.  
  43.     public function fetchAll($query, $params) {
  44.  
  45.         return $this->executeQuery($query,$params)->fetchAll(\PDO::FETCH_ASSOC);
  46.  
  47.     }
  48.  
  49.     public function fetchColumn($query, $params, $column = 0) {
  50.  
  51.         return $this->executeQuery($query,$params)->fetchColumn($column);
  52.  
  53.     }
  54.  
  55.     public function fetchAssoc($statement, array $params = array())
  56.     {
  57.         return $this->executeQuery($statement, $params)->fetch(\PDO::FETCH_ASSOC);
  58.     }
  59.  
  60.     public function fetchArray($statement, array $params = array())
  61.     {
  62.         return $this->executeQuery($statement, $params)->fetch(\PDO::FETCH_NUM);
  63.     }
  64.  
  65.     public function delete($tableExpression, array $identifier, array $types = array())
  66.     {
  67.         if (empty($identifier)) {
  68.             return FALSE;
  69.         }
  70.  
  71.         $criteria = array();
  72.  
  73.         foreach (array_keys($identifier) as $columnName) {
  74.             $criteria[] = $columnName . ' = ?';
  75.         }
  76.  
  77.         return $this->exec(
  78.             'DELETE FROM ' . $tableExpression . ' WHERE ' . implode(' AND ', $criteria),
  79.             array_values($identifier)
  80.             //is_string(key($types)) ? $this->extractTypeValues($identifier, $types) : $types
  81.         );
  82.     }
  83.  
  84.     public function insert($table, $data)
  85.     {
  86.         $fields = $values = array();
  87.         foreach ($data as $key => $value) {
  88.  
  89.             if ($value instanceof DateTime) {
  90.                 $value = $value->format('Y-m-d H:i:s');
  91.             }
  92.  
  93.             $fields[] = '`'.str_replace("`", "``", $key).'`';
  94.             $values[] = $this->_conn->quote($value);
  95.         }
  96.  
  97.         $query = "INSERT INTO `$table` (".implode(',', $fields).") VALUES (".implode(',', $values).")";
  98.  
  99.         $this->_conn->exec($query);
  100.  
  101.         return $this->_conn->lastInsertId();
  102.     }
  103.  
  104.     public function update($table, $data, $conditions)
  105.     {
  106.         if (!$data) {
  107.             return false;
  108.         }
  109.  
  110.         $updates = $wheres = array();
  111.         foreach ($data as $key => $value) {
  112.  
  113.             if ($value instanceof DateTime) {
  114.                 $value = $value->format('Y-m-d H:i:s');
  115.             }
  116.  
  117.             $updates[] = '`'.str_replace("`", "``", $key).'` = '.$this->_conn->quote($value);
  118.         }
  119.  
  120.         foreach ($conditions as $key => $value) {
  121.             $wheres[] = '`'.str_replace("`", "``", $key).'` = '.$this->_conn->quote($value);
  122.         }
  123.  
  124.         $table = '`'.str_replace("`", "``", $table).'`';
  125.  
  126.         $query = "UPDATE $table SET ".implode(', ', $updates)." WHERE ".implode(' AND ',$wheres);
  127.  
  128.         $this->_conn->exec($query);
  129.  
  130.         return true;
  131.     }
  132.  
  133.     public function query($statement)
  134.     {
  135.  
  136.         return $this->_conn->exec($statement);
  137.  
  138.     }
  139.  
  140.     public function errorCode()
  141.     {
  142.         return $this->_conn->errorCode();
  143.     }
  144.  
  145.     public function errorInfo()
  146.     {
  147.         return $this->_conn->errorInfo();
  148.     }
  149.  
  150.     public function lastInsertId($seqName = null)
  151.     {
  152.         return $this->_conn->lastInsertId($seqName);
  153.     }
  154.  
  155. }
  156.  

SELECT de una fila
Código: PHP
  1. $dbw       = new DatabaseWrapper($db);
  2. $sql        = 'SELECT `name`, email FROM Users WHERE id = ?';
  3.  
  4. $user       = $dbw->fetchRow($sql, [ $user_id ]);

SELECT
Código: PHP
  1. $dbw       = new DatabaseWrapper($db);
  2. $sql        = 'SELECT `id`, `room`, beds
  3.                              FROM Rooms WHERE hotel_id = ?';
  4.  
  5. $rooms      = $dbw->fetchAll($sql, [ $hotel_id ]);

DELETE
Código: PHP
  1. $dbw       = new DatabaseWrapper($db);
  2. $dbw->delete($table_name, [
  3.     'field' => 'value',
  4.     'field2' => 'value2'
  5. ]);

INSERT
Código: PHP
  1. $dbw       = new DatabaseWrapper($db);
  2. $row_id   = $dbw->insert($table_name, [
  3.     'field' => 'value',
  4.     'field2' => 'value2'
  5. ]);

UPDATE
Código: PHP
  1. $dbw       = new DatabaseWrapper($db);
  2. $row_id   = $dbw->update($table_name, [
  3.     'field' => 'value',
  4.     'field2' => 'value2'
  5. ],[
  6.     'id'  => 25
  7. ]);

Resumen de metodos:
  • fetchRow
  • fetchAll
  • fetchColumn
  • fetchAssoc
  • fetchArray
  • delete
  • insert
  • update
  • query
  • errorCode
  • errorInfo
  • lastInsertId


Nunca hago el new en el codigo porque mis proyectos funcionan con DI y el objeto $dbw siempre me llega al controlador. Si os interesa esta tecnica os podria explicar como.

Valarjar
Hijo de Odyn

Re:Database Wrapper para PDO +(comentario sobre performance)
« Respuesta #1 en: Junio 06, 2017, 03:30:33 am »
La verdad es que me gusta mucho como lo has codeado, algo parecido tengo yo por ahí solo que con MySqli jeje.

A darle caña! jeje