Qual è il punto dietro la creazione di una classe di adattatore PDO di livello di astrazione invece di utilizzare un PDO nativo?

1

Ho costruito una classe di adattatori PDO perché pensavo che, al momento, sarebbe stata una buona idea. Dopo aver combattuto con esso, non ha senso per me. Il design di PDO non è il modo in cui ti impedisce di dover creare adattatori speciali per un determinato database?

Per una connessione, capisco, ma mi sembra che stia sostituendo PDO con la mia versione di PDO.

Non capisco perché avrei bisogno di questo ulteriore livello di astrazione.

Ecco alcuni esempi:

public function prepare($sql, array $options = array()) {
    $this->connect();
    try {
        $this->statement = $this->connection->prepare($sql, 
            $options);
        return $this;
    }
    catch (PDOException $e) {
        throw new RunTimeException($e->getMessage());
    }
}

public function execute(array $parameters = array()) {
    try {
        $this->getStatement()->execute($parameters);
        return $this;
    }
    catch (PDOException $e) {
        throw new RunTimeException($e->getMessage());
    }
}

public function countAffectedRows() {
    try {
        return $this->getStatement()->rowCount();
    }
    catch (PDOException $e) {
        throw new RunTimeException($e->getMessage());
    }
}

public function getLastInsertId($name = null) {
    $this->connect();
    return $this->connection->lastInsertId($name);
}

EDIT: ho trovato questo. Penso che potrei essere in overkill. Potrei avere questa classe per altre cose, ma non un PDO nativo senza una ragione più convincente.

link

    
posta johnny 23.10.2014 - 18:43
fonte

1 risposta

3

In effetti, avresti potuto usare direttamente PDO. L'unica cosa reale che fa è rilanciare PDOException come RunTimeException , una pratica che dovrebbe essere evitata a tutti i costi.

Detto questo, PDO non ti impedisce di dover creare adattatori speciali per un dato database, poiché diversi database hanno sintassi e funzionalità diverse che non possono essere gestite da PDO. Funziona per cose semplici come PDOStatement::rowCount() , ma PDO non ti aiuterà se, ad esempio, hai bisogno di LIMIT/OFFSET del numero di risultati in MySQL e Microsoft SQL, costringendoti a scrivere LIMIT/OFFSET query per uno e WHERE rowNumber BETWEEN ... AND ... per un altro.

Inoltre, la presenza di PDO non significa che non dovresti avere un livello database: il tuo livello aziendale non dovrebbe chiamare direttamente il PDO.

Esempio

Se un sito web deve visualizzare il numero di utenti, il livello aziendale chiamerà il livello del database IDatabase allo stesso modo di questo:

$countUsers = $this->data->countAllUsers();

Quindi, avrai un'implementazione per Microsoft SQL Server:

class SqlServerDatabase implements IDatabase
{
    ...
    public function countAllUsers()
    {
        $query = 'select count(1) from [Community].[User]';
        $statement = $this->connection->prepare($query);
        $statement->execute();
        return $statement->fetchColumn();
    }
    ...
}

e un altro per MySQL:

class SqlServerDatabase implements IDatabase
{
    ...
    public function countAllUsers()
    {
        $query = 'select count(*) from 'user'';
        $statement = $this->connection->prepare($query);
        $statement->execute();
        return $statement->fetchColumn();
    }
    ...
}

Se hai un sacco di conteggio delle tabelle, potresti rifattarti per ridurre la duplicazione del codice. Senza PDO, non sarai in grado di farlo. Con PDO, puoi:

abstract class DatabaseCommon
{
    protected function countAllRows(TableName $tableName, $preferOneToAsterisk = false)
    {
        $query = $preferOneToAsterisk ?
            'select count(1) from ' . $tableName->sanitize() :
            'select count(*) from ' . $tableName->sanitize();

        $statement = $this->connection->prepare($query);
        $statement->execute();
        return $statement->fetchColumn();
    }
}

class SqlServerDatabase extends DatabaseCommon implements IDatabase
{
    public function countAllUsers()
    {
        return $this->countAllRows(
            new MicrosoftSqlTableName('Community', 'User'),
            true
        );
    }
}

class SqlServerDatabase extends DatabaseCommon implements IDatabase
{
    public function countAllUsers()
    {
        return $this->countAllRows(new MySqlTableName('user'));
    }
}
    
risposta data 23.10.2014 - 19:33
fonte

Leggi altre domande sui tag