[RISOLTO]Classe database: connessione in costruttore?

peppeocchi

Utente Attivo
20 Apr 2013
30
0
0
Ciao a tutti,
ho un dilemma che mi perseguita ormai da settimane: è corretto effettuare la connessione al database nel costruttore di una classe, estesa poi da altre classi?
Faccio subito qualche piccolo esempio.

Ho una classe generica DbClass
PHP:
<?php
class DbClass {
	protected $host = "XXX";
	protected $username = "XXX";
	protected $password = "XXX";
	protected $dbName = "XXX";

	protected $_mysqli;
	protected $_query;

	public function __construct() {
		$this->_mysqli = new mysqli($this->host,$this->username,$this->password,$this->dbName);
		if($this->_mysqli->connect_errno) {
			echo "Connection failed: ".$this->_mysqli->connect_error;
			exit();
		}
	}
......
	public function __destruct() {
		$this->_mysqli->close();
	}

Ho poi altre classi che ne estendono le funzionalità, ad esempio
PHP:
<?php

require_once "classDB.php";

class User extends DbClass {
	private $Uusername;
	private $Upassword;
......
PHP:
<?php

require_once "classDB.php";

class AuthUser extends DbClass {
......

Quindi ogni volta che creo un oggetto di una di queste classi, sono automaticamente connesso al database.
E' corretto mettere nel costruttore la connessione al database?
Che problemi posso avere se nello stesso script creo oggetti di classi diverse? Tipo
PHP:
$user = new User;
.....
.....
$auth = new AuthUser;
.....

Dovrei modificare la DbClass in qualche altro modo, modificando/togliendo la connessione nel costruttore?

Grazie.
 
Ciao, anch'io uso più o meno la stessa tecnica
solo che non estendo un altra classe per la connessione al db, anche perchè mysqli è già una classe, mi connetto direttamente nel costruttore di ogni classe che necessita del database e mi disconnetto nel suo distruttore
fino ad ora non ho riscontrato nessun problema
non so dirti se teoricamente sia una soluzione ottimale ma a livello pratico è molto efficiente
 
Un altra tecnica è quella di utilizzare un pattern singleton

PHP:
class DbClass {
    private $instance;
    protected $host = "XXX";
    protected $username = "XXX";
    protected $password = "XXX";
    protected $dbName = "XXX";

    protected $_mysqli;
    protected $_query;

    private function __construct() {
        $this->_mysqli = new mysqli($this->host,$this->username,$this->password,$this->dbName);
        if($this->_mysqli->connect_errno) {
            echo "Connection failed: ".$this->_mysqli->connect_error;
            exit();
        }
    }

    public static function getIstance()
    {
        if( is_null(self::$instance) )
       {
             self::$instance = new self();
       }
        
         return self::$instance;
    }

    public function __destruct() {
        $this->_mysqli->close();
    }

PHP:
require_once "classDB.php";

class AuthUser { 
    
    private $db;

    public function __construct() {
        $this->db = classDB::getIstance();

        $this->db->query("SELECT * FROM tabella");
    }


In questo modo tutti gli oggetti istanzieranno una sola connessione. Il primo a chiamare classDB::getIstance() creerà l'istanza, tutti gli altri riceveranno la prima istanza creata.
 
Ultima modifica:
Grazie mille per le risposte! Interessante il pattern singleton, molto interessante!
Ho appena modificato il codice, c'era un errore (credo) nella dichiarazione di $instance, infatti ho ricevuto subito un Fatal error, risolto modificando con
PHP:
private static $instance;

solo una curiosità, probabilmente stupida, non c'è un modo per evitare la variabile $db nelle altre classi?

Grazie ancora!
 
Ho appena modificato il codice, c'era un errore (credo) nella dichiarazione di $instance, infatti ho ricevuto subito un Fatal error, risolto modificando con
PHP:
private static $instance;

hai fatto bene, è giusto così... avevo scritto il codice direttamente sul forum senza pravorlo....

solo una curiosità, probabilmente stupida, non c'è un modo per evitare la variabile $db nelle altre classi?


certo... puoi chiedere l'ustanza direttamente nei metodi

PHP:
function blabla()
{
    $db = classDB::getIstance();
    $db->query("Select * from tabella");
}

oppure ancora più comodamente

PHP:
function blabla()
{
    classDB::getIstance()->query("Select * from tabella");
}
 
Grazie ancora per la risposta!

Ho un piccolo problema adesso, con il distruttore.

Codice:
Fatal error: Call to a member function close() on a non-object in /path/classDB.php on line 48

che sarebbe questa parte del codice

PHP:
public function __destruct() {
		$this->_mysqli->close();
	}

Tengo a precisare che classDB non la uso mai direttamente, ma sempre indirettamente con le classi estese.

Qualche idea?
 
toglila

PHP:
public function __destruct() { }

anche perchè come fai a sapere con esatezza quando chiudere la connessione?? tanto vale lasciarlo fare al garbage collector. Ti ricordo che tutti gli oggetti in php vivono all'interno della richiesta http, terminata quella vengono tutti distrutti...
 
Si, hai probabilmente ragione, fin'ora non mi è capitato di distruggere un'oggetto prima della fine di uno script, in realtà avevo implementato quella funzione in previsione di opzioni che non ho mai usato in pratica...

Grazie ancora!
 

Discussioni simili