Database Wrapper para PDO +(comentario sobre performance)

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.24748301506042

With 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.

PandaGG
Lok'tar ogar

Dejar respuesta

Please enter your comment!
Please enter your name here

Sponsor

Últimos

Migliori casinò online attendibili: come salvaguardare le tue dati riservate e le tue entrate

In Italia, i Migliori casinò online richiamano ogni giorno un volume in aumento di appassionati. Numerosi iscritti consultano ogni giorno le app e i...

Jak fungují turnaje a soutěže na Bassbet Casino

ÚvodTurnaje a soutěže na online herních platformách, jako je Bassbet Casino, představují atraktivní způsob, jak mohou hráči zvýšit své šance na výhru a zažít...

Nyerőgépek RTP mutatójának jelentősége

BevezetésA nyerőgépek RTP (Return to Player) mutatója kulcsfontosságú tényező a szerencsejáték-iparban, különösen Magyarországon. Az RTP mutató megértése elengedhetetlen az iparági elemzők számára, mivel ez...

Recenze Joker8 Casino: Co potřebujete vědět

ÚvodJoker8 Casino se stává stále populárnější volbou mezi českými hráči a jeho recenze jsou důležité pro analýzu trhu s online hazardními hrami. Pro průmyslové...

Frumzi online kasino: Přehled a rady pro průmyslové analytiky

ÚvodFrumzi online kasino se stává stále populárnějším místem pro hráče v České republice. Tento trend je důležitý pro průmyslové analytiky, kteří sledují vývoj online...