2010-04-05 17 views
7

Nel mio progetto ho una classe di database che uso per gestire tutte le cose MySQL. Si collega a un database, esegue query, intercetta errori e chiude la connessione.Utilizzo di una classe di database nella mia classe utente

Ora ho bisogno di creare un'area membri sul mio sito, e stavo per creare una classe utenti che gestisse la registrazione, l'accesso, le modifiche/resettazioni password/nome utente e la disconnessione. In questa classe di utenti ho bisogno di usare MySQL per ovvi motivi ... che è ciò per cui è stata creata la mia classe di database.

Ma sono confuso su come utilizzare la classe di database nella classe di utenti. Vorrei creare un nuovo oggetto di database per la mia classe utente e quindi chiuderlo ogni volta che un metodo in quella classe è finito? Oppure faccio in qualche modo una classe di database 'globale' che può essere usata in tutto il mio intero script (se questo è il caso ho bisogno di aiuto, non ho idea di cosa fare lì.)

Grazie per qualsiasi feedback che puoi dare me.

risposta

0

Poiché si utilizza il database come oggetto, perché non aggiungere solo metodi all'oggetto che la "classe utenti" può impiegare per occuparsi delle cose che deve fare. La classe users può contenere un puntatore alla classe del database. La classe del database proteggerà il tuo database e assicurerà che la classe degli utenti lo stia utilizzando in modo appropriato.

+1

Sembra molto simile a unire le due classi. Preferirei una soluzione in cui le classi fossero completamente indipendenti, a meno che mi manchi qualcosa? – Josh

+0

Il design OO riguarda l'incapsulamento. Per me, ha senso incapsulare il database in modo indipendente e quindi avere classi che accedano a esso, in modo che esso controlli da solo l'accesso al database. Tuttavia, altri design sono possibili. Avere due classi che entrambi accedono direttamente al database è possibile, anche se la mia opinione è che aggiunge ulteriore complessità. – WhirlWind

+0

Suppongo che un altro modo per farlo sia istanziare un'istanza della classe database che si connette al database, quindi usare una classe separata per fare cose "utente" tramite un handle di database recuperato dalla classe del database ... Questo dovrebbe funzionare, se preferiscilo – WhirlWind

1

Come ha detto, inserire tutte le funzioni nella classe del database e utilizzare l'oggetto database per accedere a tali funzioni dalla classe utente. Questo dovrebbe essere il metodo migliore nel tuo caso. Ad esempio:
global $database;
userclassvar = $database->doSomething();

1

Quello che mi piace fare è rendere la classe database con il Singleton pattern in mente. In questo modo, se hai già un oggetto di database, lo recupera, altrimenti ne crea uno nuovo. Per esempio:

Database.class.php 

class Db 
{ 
    protected static $_link; 

    private function __construct() 
    { 
     // access your database here, establish link 
    } 

    public static function getLink() 
    { 
     if(self::_link === null) { 
      new Db(); 
     } 
     return self::_link; 
    } 

    // etc. 

} 


User.class.php 

class User 
{ 
    protected $_link; // This will be the database object 
    ... 

    public function __construct() 
    { 
     $this->_link = Db::getLink(); 
    } 

} 

E ora si può utilizzare $_link proprietà User s' a fare le funzioni di database, come $this->_link->query(...). Non devi necessariamente inserire lo Db::getLink() nel costruttore se la tua classe non deve interagire tanto con il database.

+0

Ehi, ho tentato di implementare un concetto simile, quale sarebbe il codice per stabilire un tale collegamento? Ho provato a utilizzare self :: _ link = e $ this -> _ link, ma nessuno dei due mi consentirà di impostare il collegamento. – MichaelH

21

Semplice, processo a 3 fasi. 1/Crea un oggetto di database. 2/Dagli al costruttore della classe utente. 3/Usalo nei metodi utente.

Piccolo esempio.

File Database.class.php:

<?php 
class Database{ 
    public function __construct(){ 
    // Connects to database for example. 
    } 

    public function query($sqlQuery){ 
    // Send a query to the database 
    } 
    [...] 
} 

In User.class.php:

<?php 

class User{ 
    private $_db; 
    public function __construct(Database $db){ 
    $this->_db = $db; 
    } 

    public function deleteUser(){ 
    $this->_db->query('DELETE FROM Users WHERE name = "Bobby"'); 
    } 
} 

Ora, in userManager.php ad esempio:

<?php 
$db = new Database(); 
$user = new User($db); 
// Say bye to Bobby : 
$user->deleteUser(); 

Se vuoi il nome attuale di questa vecchia tecnica, google "Dependency Injection". Il modello Singleton in php svanirà presto.

+0

Probabilmente la migliore risposta che avrei potuto sperare, l'ho scoperto chiaramente ora. Grazie. :) – Josh

+0

... anche se non riesco ad accettare questa risposta senza registrarmi, lol – Josh

+4

Quindi ... registrati? –

0

Penso che l'approccio migliore sarebbe quello di creare la classe del database che si instace da subito su un database.php e quindi includerlo su user.php. quindi ogni volta che si crea una funzione che richiede un database, si globalizza l'oggetto del database.

Controllare questo. databse.php

<?php 
require_once ('includes/config.php'); 

class MysqlDb{ 
public $connection; 
private $last_query; 
private $magic_quotes_active; 
private $real_escape_string_exists; 


public function __construct() { 
    $this->open_connection(); 
    $this->magic_quotes_active = get_magic_quotes_gpc(); 
$this->real_escape_string_exists = function_exists("mysql_real_escape_string"); 
} 

public function open_connection() { 
    $this->connection = mysql_connect(DBHOST,DBUSER,DBPASS); 
    if(!$this->connection){ 
     die("Could not Connect ".mysql_error()); 
    }else{ 
     $db = mysql_select_db(DB, $this->connection); 
    } 
} 

public function close_connection(){ 
    if(isset($this->connection)){ 
     mysql_close($this->connection); 
     unset($this->connection); 
    } 
} 

public function query($sql){ 
    $this->last_query = $sql; 
    $results   = mysql_query($sql, $this->connection); 
    $this->comfirm_query($results); 
    return $results; 
} 

private function comfirm_query($results){ 
    if(!$results){ 
     $output  = "Query Failed " .mysql_error()."<br />"; 
     $output .= "Last Query: " . $this->last_query; 
     die($output); 
    } 
} 

public function escape_value($value){ 

if($this->real_escape_string_exists) { 
    if($this->magic_quotes_active) { $value = stripslashes($value); } 
    $value = mysql_real_escape_string($value); 
} else { 
    if(!$this->magic_quotes_active) { $value = addslashes($value); } 
} 
return $value; 
} 

public function fetch_array($results){ 
    return mysql_fetch_array($results);   
} 

public function num_row($results){ 
    return mysql_num_rows($results); 
} 

public function insert_id(){ 
    return mysql_insert_id($this->connection); 
} 

public function affected_row(){ 
    return mysql_affected_rows(); 
} 
} 
$database = new MysqlDb(); 

?> 

qui è l'user.php

<?php 
require_once ('includes/database.php'); 

class User { 

public $id; 
public $fName; 
public $lName; 
Public $userName; 
public $password; 
public $email; 
public $acess; 

public static function find_all(){ 
    global $database; 
    return self::find_by_sql("SELECT * FROM users");  
} 

public static function find_by_id($id=0){ 
    global $database; 
    $results_array = self::find_by_sql("SELECT * FROM users where id={$id}"); 
    return !empty($results_array)? array_shift($results_array) : false; 
} 

public static function find_by_sql($sql){ 
    global $database; 
    $results = $database -> query($sql); 
    $object_array = array(); 
    while($row = $database -> fetch_array($results)){ 
     $object_array[] = self::instantiate($row); 
    } 
    return $object_array; 
} 

public static function instantiate($row){ 
    $user = new self; 
    foreach($row as $attribute => $value){ 
     if($user -> has_attribute($attribute)){ 
      $user -> $attribute = $value; 
     } 
    } 
    return $user; 
} 

private function has_attribute($attribute){ 
    $object_vars = get_object_vars($this); 
    return array_key_exists($attribute, $object_vars); 

} 
} 

?> 
0

Ecco una soluzione che utilizza DOP.

<?php 
    class Database { 
     private static $dbh; 

     public static function connect() { 
      $host = "mysql:dbname=YOUR_DB_NAME;host=YOUR_DB_SERVER"; 
      $username = "YOUR_USERNAME"; 
      $password = "YOUR_PASSWORD"; 
      try { 
       self::$dbh = new PDO($host, $username, $password); 
       self::$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT); 
       self::$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); 
       self::$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
      } catch(PDOException $e){ 
       $error_message = $e->getMessage(); 
       exit(); 
      } 
      return self::$dbh; 
     } 
    } 

    class MYObject { 
     public static $dbh = null; 

     public function __construct(PDO $db = null) { 
      if($db === null){ 
       $this->dbh = Database::connect(); 
      } else { 
       $this->dbh = $db; 
      } 
     } 
    } 

    class User extends myObject { 
     public function __construct($id = null, PDO $db = null) { 
      if($db === null){ 
       parent::__construct(); 
      } else { 
       parent::__construct($db); 
      } 

      if($id !== null){ 
       return $this->select($id); 
      } 
     } 

     public function select($id) { 
      $retVal =false; 
      try { 
       $stmt = $this->dbh->prepare("SELECT..."); 
       $stmt->execute(); 

       if($stmt->rowCount()==1){ 
        $row = $stmt->fetchAll(PDO::FETCH_ASSOC); 
        $retVal =json_encode($row); 
       } 
      } catch (PDOException $e) { 
       $error_message = $e->getMessage(); 
       exit(); 
      } 
      return $retVal; 
     } 
    } 
?> 
Problemi correlati