Os traigo un Wrapper que uso habitualmente en mis proyectos PHP. Lo suelo tener integrado en mi esqueleto Slim 3 pero lo he 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 cogí de algún otro Wrapper, ORM o a saber.
En mis proyectos es importante que el acceso a la base de datos sea rápido y muchas veces el uso de un ORM como Doctrine o Eloquent no son para nada rápidos:
With pure PDO:
memory: 0.0044288635253906
seconds: 0.24748301506042With DBAL and autoload:
memory: 0.97610473632812
seconds: 0.29042816162109
Extraído de Reddit y de gonzalo123.com. No es el código mas elegante ni de la ultima versión de PHP, de hecho tengo que actualizarlo para poder usar toda la potencia de PDO, aun así, aquí os lo pego y luego un tutorial de como usarlo (os prometo que lo actualizare para sacarle mas jugo):
class DatabaseWrapper { private $_conn; public function __construct( $db ) { $pdo = new PDO($db, $db, $db, $db); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); $this->_conn = $pdo; } protected function exec($query, $params) { if (strpos($query,'SELECT') !== false) { return $this->executeQuery($query, $params)->fetchAll(\PDO::FETCH_ASSOC); } return $this->executeQuery($query, $params)->rowCount(); } protected function executeQuery($query, $params) { $statment = $this->_conn->prepare($query); $statment->execute($params); return $statment; } public function fetchRow($query, $params = array()) { return $this->executeQuery($query,$params)->fetch(\PDO::FETCH_ASSOC); } public function fetchAll($query, $params) { return $this->executeQuery($query,$params)->fetchAll(\PDO::FETCH_ASSOC); } public function fetchColumn($query, $params, $column = 0) { return $this->executeQuery($query,$params)->fetchColumn($column); } public function fetchAssoc($statement, array $params = array()) { return $this->executeQuery($statement, $params)->fetch(\PDO::FETCH_ASSOC); } public function fetchArray($statement, array $params = array()) { return $this->executeQuery($statement, $params)->fetch(\PDO::FETCH_NUM); } public function delete($tableExpression, array $identifier, array $types = array()) { if (empty($identifier)) { return FALSE; } $criteria = array(); foreach (array_keys($identifier) as $columnName) { $criteria[] = $columnName . ' = ?'; } return $this->exec( 'DELETE FROM ' . $tableExpression . ' WHERE ' . implode(' AND ', $criteria), array_values($identifier) //is_string(key($types)) ? $this->extractTypeValues($identifier, $types) : $types ); } public function insert($table, $data) { $fields = $values = array(); foreach ($data as $key => $value) { if ($value instanceof DateTime) { $value = $value->format('Y-m-d H:i:s'); } $fields[] = '`'.str_replace("`", "``", $key).'`'; $values[] = $this->_conn->quote($value); } $query = "INSERT INTO `$table` (".implode(',', $fields).") VALUES (".implode(',', $values).")"; $this->_conn->exec($query); return $this->_conn->lastInsertId(); } public function update($table, $data, $conditions) { if (!$data) { return false; } $updates = $wheres = array(); foreach ($data as $key => $value) { if ($value instanceof DateTime) { $value = $value->format('Y-m-d H:i:s'); } $updates[] = '`'.str_replace("`", "``", $key).'` = '.$this->_conn->quote($value); } foreach ($conditions as $key => $value) { $wheres[] = '`'.str_replace("`", "``", $key).'` = '.$this->_conn->quote($value); } $table = '`'.str_replace("`", "``", $table).'`'; $query = "UPDATE $table SET ".implode(', ', $updates)." WHERE ".implode(' AND ',$wheres); $this->_conn->exec($query); return true; } public function query($statement) { return $this->_conn->exec($statement); } public function errorCode() { return $this->_conn->errorCode(); } public function errorInfo() { return $this->_conn->errorInfo(); } public function lastInsertId($seqName = null) { return $this->_conn->lastInsertId($seqName); } }
SELECT de una fila
$dbw = new DatabaseWrapper($db); $sql = 'SELECT `name`, email FROM Users WHERE id = ?'; $user = $dbw->fetchRow($sql, );
SELECT
$dbw = new DatabaseWrapper($db); $sql = 'SELECT `id`, `room`, beds FROM Rooms WHERE hotel_id = ?'; $rooms = $dbw->fetchAll($sql, );
DELETE
$dbw = new DatabaseWrapper($db); $dbw->delete($table_name, );
INSERT
$dbw = new DatabaseWrapper($db); $row_id = $dbw->insert($table_name, );
UPDATE
$dbw = new DatabaseWrapper($db); $row_id = $dbw->update($table_name, ,);
Resumen de metodos:
-
- fetchRow
- fetchAll
- fetchColumn
- fetchAssoc
- fetchArray
- delete
- insert
- update
- query
- errorCode
- errorInfo
- lastInsertId
Nunca hago el new en el código porque mis proyectos funcionan con DI y el objeto $dbw siempre me llega al controlador. Si os interesa esta técnica os podría explicar como.