OOP - Devo impostare la connessione del database come "pubblica" perché altre classi lo usino, anche se potrebbe non essere sicuro?

3

Ho una classe base Database e ha una proprietà mysqli (un oggetto stesso) che contiene le informazioni di connessione. Altre classi utilizzano questa classe per leggere e manipolare il database.

Ci sono funzioni incorporate in qualsiasi oggetto di connessione al database (in questo caso,% di% di PHP di%,% di% di co_de ecc.), che ho bisogno di usare in altre classi.

Il problema è che in realtà non voglio impostare la proprietà di connessione come mysqli::multi_query poiché credo che sia una cattiva pratica farlo in qualsiasi proprietà, specialmente non una con le informazioni di connessione.

Quindi cosa dovrei fare? Dovrei comunque impostarlo su mysqli::next_result o dovrei creare manualmente una funzione per ogni funzione incorporata che devo usare?

    
posta Sipo 20.10.2015 - 13:06
fonte

1 risposta

4

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

    
risposta data 20.10.2015 - 13:14
fonte

Leggi altre domande sui tag