2013-12-18 11 views
13

Ho fatto qualche ricerca sull'utilizzo di un databasewrapper per i miei dati. Tuttavia, ho letto alcuni post in cui le persone affermano che non dovresti usare PDO per un databasewrapper perché è già uno.Un wrapper pdo è davvero eccessivo?

Potrebbe essere così, ma sono ancora convinto che abbia molti vantaggi.

  1. Gestisci tutte le azioni di dati (crude) in una classe, non distribuite sui file del tuo sito web. Quindi è molto più facile eseguire il debug e gestire gli errori.
  2. È possibile modificare facilmente la classe con un'altra classe di database.
  3. Non è necessario ripetere il codice, basta chiamare il codice nella databaseclass
  4. Opzionalmente è possibile estendere la classe con ad esempio la registrazione, i test statistici, ...

Esempio:

<?php 
class Database 
{ 
    public $connection; 
    private $host = ""; 
    private $username = ""; 
    private $password = ""; 
    private $dbname = ""; 

    public function __construct(){  
     $this->connection = new PDO("mysql:host=$this->host;dbname=$this->dbname",$this->username,$this->password,array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")); 
     $this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
    } 

    public function insert($query, array $data){   
     $this->connection->prepare($query)->execute($data);  
     return $this->connection->lastInsertId(); 
    } 

    public function update($query, array $data) { 
     $stmt = $this->executeQuery($query,$data); 
     return $stmt->rowCount();  
    } 

    public function delete($query, array $data) { 
     $stmt = $this->executeQuery($query,$data); 
     return $stmt->rowCount();  
    } 

    public function findOne($query, array $data = null){   
     $stmt = $this->executeQuery($query,$data);   
     return $stmt->fetchObject(); 
    } 

    public function findMany($query, array $data = null){ 
     $stmt = $this->executeQuery($query,$data); 
     return($stmt->fetchAll(PDO::FETCH_OBJ)); 
    } 

    public function executeQuery($query,$data = null){ 
     $stmt = $this->connection->prepare($query); 
     $stmt->execute($data); 
     return $stmt; 
    } 
} 
?> 

Invece di ripetere costantemente tutti i passaggi per il recupero dei dati, è possibile chiamare get() e passare una query e alcuni parametri facoltativi. Questo è molto più efficiente di ogni volta che si apre una connessione, si eseguono 3 linee di codice e si chiude.

$db->get("select * from user where id = ?",array(1)); 
+0

"Tutti i passaggi ..." - ce ne sono davvero tanti? PDO ti permette di scrivere 'foreach ($ pdo-> query (...) come $ row)', che è tanto minimale quanto per un'istruzione non preparata. Interagire con il database è costoso e dovrebbe avvenire solo con metodi molto specifici per iniziare anziché "dappertutto", non capisco perché debba sempre succedere in una singola riga. – deceze

+0

Cosa intendi con metodi molto specifici invece che dappertutto? –

+0

MVC, separazione dei dubbi. Dovresti avere alcuni punti concentrati nel tuo livello del modello in cui i dati vengono recuperati dal database. Per esempio. 'UserService :: getAllActiveUsers()' o 'PostService :: updatePost ($ id, array $ data)'. L'unico compito di questi metodi è quello di interagire con il database in un modo specifico. All'interno, dovresti spendere quante più righe su una corretta query del database, se necessario, non c'è alcun vantaggio nel farne una singola riga. Avere un tale "semplice involucro" ti fa semplicemente sedurre per interrogare il tuo database da tutto il posto ad hoc invece di creare questi metodi centrali una sola volta. – deceze

risposta

6

Si dice perché la maggior parte tentativi di creare un wrapper DOP sono davvero impotente e rendere le cose peggio di DOP crudo.
Anche i locali, uno sta scrivendo il loro wrapper basato su, sono per lo più sbagliati.

Prendiamo vostra:

gestire tutti i dati in una classe, si diffonde attraverso i vostri file del sito web.

Abbastanza dichiarazione vaga, senza significato particolare. Sicuramente gestirai i tuoi dati su tutta l'applicazione ma non utilizzando PDO non elaborato ma utilizzando la tua classe.

È possibile modificare facilmente la classe con un'altra banca dati.

Ma un delirio. Non è possibile attenersi ai due metodi di supporto, a volte è necessario utilizzare l'istanza PDO non elaborata.

Non è necessario ripetere il codice, basta chiamare il codice nella databaseclass

questo è del tutto vero. Ma non così utile come con qualsiasi altra API.

Opzionalmente è possibile estendere la classe con ad esempio la registrazione, statistica test

Si tratta di una vera e propria una - obiezioni.

Questo è molto più efficiente di ogni volta che si apre una connessione, eseguire 3 righe di codice e chiuderlo.

questo è falso. Nessuno ti chiede ogni volta di aprire una connessione, eseguire 3 righe di codice e chiuderla. Anche con la connessione PDO raw viene aperta una sola volta.

Tuttavia, la vostra implementazione è abbastanza buona. Non aggiunge troppo al PSO raw (in realtà, abbrevia le ripetizioni solo di una sola riga), ma è comunque ragionevole. Quindi, definirei questo approccio piuttosto efficace.

Alcuni suggerimenti:

  1. v'è infatti alcun senso la memorizzazione delle credenziali di database come proprietà di classe. Servivano solo nel costruttore e da nessun'altra parte
  2. Perché non creare una connessione direttamente nel costruttore, senza la necessità di un ulteriore metodo?
  3. public function getOne() sarebbe un'aggiunta indispensabile al tuo set.
  4. Hai bisogno di fare $ connessione pubblica - almeno fino a quando si fanno tutti i metodi disponibili sia da DOP e PDOStatement
+0

Con la mia prima affermazione intendevo la gestione di tutte le operazioni del database. Era davvero piuttosto vago. Vedo spesso che le persone costruiscono la loro pagina web utilizzando costantemente operazioni di crudit attraverso la pagina.Invece, sono convinto che la migliore pratica consiste nel consentire a una singola classe di gestire tutte le operazioni del database. –

+1

Ben DOP già finge di essere una tale classe. Quindi, parlando di DOP, la tua argomentazione non è rilevante. Il problema principale con i wrapper, che le persone che scrivono, hanno anche meno conoscenza dei creatori di PDO e peggiorano le cose. Se solo execute() restituisse $ questo invece di booleano - renderebbe la tua classe effettivamente obsoleta. –

+1

In effetti, capisco, non sono sicuramente migliore dei creatori di PDO :), non cerco anche di migliorarlo, ma lo uso in modo pratico creando metodi che restituiscano oggetti. –

2

'Overkill' è soggettivo. Questo è per te decidere per il tuo caso particolare. Per quanto riguarda le prestazioni, dubito che noterai qualche differenza.

Ci sono alcuni possibili vantaggi nel fare qualcosa di simile. Ad esempio, è possibile incorporare il profilo di query e la registrazione dell'applicazione nella classe. E, come fai notare, hai la possibilità di strutturare le query in un modo che è più semplice con cui puoi lavorare e mantenerle.

D'altra parte, il codice sarà meno portabile se si basa sulla classe del wrapper. Non puoi quindi prendere quel codice e usarlo con il codice che si basa su PDO. È possibile aggirare alcune di queste limitazioni estendendo la classe PDO, piuttosto che creare un wrapper per questo.