L'intero scopo del wrapping di un driver di base del database PHP è quello di fornire l'interfaccia personalizzata per la gestione delle richieste del database. Rendere pubblica la proprietà mysqli
sfugge completamente allo scopo e in primo luogo non avresti davvero bisogno della tua classe personalizzata.
L'approccio migliore sarebbe creare un DatabaseInterface
, avere una classe o classi implementarlo, classi, che, preferibilmente nel loro costruttore, prendere un driver di base del database PHP (sia esso mysqli o PDO) e usare DatabaseInterface
come parametri per le classi che richiedono l'interazione con il database.
In questo modo fornisci la tua astrazione, su cui hai il pieno controllo, e non sono limitati alla singola implementazione.
Ulteriori dettagli e esempio di implementazione
In PHP hai generalmente due opzioni raccomandate per la connessione al database.
- utilizzando
PDO
- utilizzando
mysqli
Il problema è PDO
e mysqli
forniscono un'interfaccia diversa per l'interrogazione, creando transazioni, quindi se hai usato per esempio mysqli
nella tua applicazione direttamente e poi vuoi passare a PDO
, dovresti rifattorizzare ogni singola chiamata al database nella tua app.
Usa le interfacce per l'astrazione
Crea un'interfaccia, che rappresenterà la tua interfaccia personale per le chiamate al database. Ecco un esempio molto semplice di come possono apparire alcuni dei suoi metodi.
interface MyDatabase
{
public function beginTransaction();
public function commitTransaction();
public function doQuery($sql);
}
In questo momento vuoi usare mysqli
, quindi crei una nuova classe, MyMySQLiDriver
, che implementerà l'interfaccia MyDatabase
e prenderai un oggetto mysqli
nel suo costruttore come parametro, oppure puoi usa le funzioni di programmazione procedurale mysqli_*
.
class MyMySQLiDriver implements MyDatabase
{
protected $mysqli;
public function __construct($mysqli)
{
$this->mysqli = $mysqli;
}
public function beginTransaction() { /* use $this->mysqli here */ }
public function commitTransaction() { /* use $this->mysqli here */ }
public function doQuery($sql) { /* use $this->mysqli here */ }
}
Ovunque nel tuo codice, se vuoi usare un database, passerai un oggetto di MyDatabase
(l'interfaccia) come parametro e userai i suoi metodi.
function IAmUsingTheDatabase(MyDatabase $db)
{
$db->beginTransaction();
$db->doQuery("SELECT * ...");
$db->commitTransaction();
}
Tieni presente che IAmUsingTheDatabase
non ha alcuna idea se stai utilizzando PDO
, mysqli
o qualsiasi altra cosa. Vuole utilizzare il database e utilizza l'interfaccia che hai fornito.
Come ho detto nei commenti sotto questo post, se, in futuro, non vuoi più usare MyMySQLiDriver
, crei una nuova classe, sia essa MyPDODriver
o qualsiasi altra cosa, che ancora implementa l'interfaccia MyDatabase
.
Dove andare da qui
Puoi studiare di più su questo argomento sotto Inversion of Control (questo è direttamente legato a Iniezione delle dipendenze e beneficia molto del Schema di strategia ).