Menggunakan kelas database di kelas pengguna saya

Dalam proyek saya, saya memiliki kelas database yang saya gunakan untuk menangani semua hal MySQL. Ia terhubung ke database, menjalankan kueri, menangkap kesalahan, dan menutup koneksi.

Sekarang saya perlu membuat area anggota di situs saya, dan saya akan membangun kelas pengguna yang akan menangani registrasi, login, perubahan kata sandi/nama pengguna/reset dan logout. Di kelas pengguna ini saya perlu menggunakan MySQL untuk alasan yang jelas... untuk itulah kelas database saya dibuat.

Tapi saya bingung bagaimana saya akan menggunakan kelas database saya di kelas pengguna saya. Apakah saya ingin membuat objek database baru untuk kelas pengguna saya dan kemudian menutupnya setiap kali metode di kelas itu selesai? Atau apakah saya membuat kelas database 'global' yang dapat digunakan di seluruh skrip saya (jika ini masalahnya, saya memerlukan bantuan untuk itu, tidak tahu harus berbuat apa di sana.)

Terima kasih atas masukan apa pun yang dapat Anda berikan kepada saya.


person Josh    schedule 05.04.2010    source sumber


Jawaban (6)


Sederhana, proses 3 langkah. 1/ Buat objek basis data. 2/ Berikan ke konstruktor kelas pengguna Anda. 3/ Gunakan dalam metode pengguna.

Sedikit contoh.

File Database.kelas.php :

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

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

Di Pengguna.kelas.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"');
  }
}

Sekarang, di userManager.php misalnya:

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

Jika Anda ingin nama trendi saat ini untuk teknik lama ini, google "Injeksi Ketergantungan". Pola Singleton di php akan segera hilang.

person Arkh    schedule 07.04.2010
comment
Mungkin jawaban terbaik yang bisa saya harapkan, saya memahaminya dengan jelas sekarang. Terima kasih. :) - person Josh; 08.04.2010
comment
...walaupun sepertinya saya tidak bisa menerima jawaban ini tanpa mendaftar, haha - person Josh; 08.04.2010
comment
Ini mungkin sudah berumur bertahun-tahun, tapi terima kasih telah memposting ini -- telah mencari-cari selama 2 hari mencoba mencari tahu mengapa salah satu kelas saya tidak menarik id koneksi kelas DB saya, yang mengakibatkan $this-›_link tidak dimulai, memberikan mysqli_ [bla bla] saya diperlukan sebagai parameter pertama. Terima kasih lagi. - person MrMarlow; 11.02.2014

Seperti yang dia katakan, letakkan semua fungsi Anda di kelas database dan gunakan objek database untuk mengakses fungsi tersebut dari kelas pengguna Anda. Ini harus menjadi metode terbaik dalam kasus Anda. Misalnya:
global $database;
userclassvar = $database->doSomething();

person Joey Ezekiel    schedule 05.04.2010

Yang ingin saya lakukan adalah membuat kelas database dengan mempertimbangkan pola Singleton. Dengan begitu, jika Anda sudah memiliki objek database, objek tersebut hanya akan diambil saja, jika tidak maka akan dibuat objek baru. Misalnya:

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();
    }

}

Dan sekarang Anda dapat menggunakan properti $_link User untuk melakukan fungsi database, seperti $this->_link->query(...). Anda tidak perlu memasukkan Db::getLink() ke dalam konstruktor jika kelas Anda tidak perlu terlalu banyak berinteraksi dengan database.

person Oliver Nagy    schedule 06.04.2010
comment
Hai, saya telah mencoba menerapkan konsep serupa, kode apa yang akan digunakan untuk membuat tautan seperti itu? Saya mencoba menggunakan self::_link = dan $this-›_link juga, namun saya tidak dapat mengatur tautannya. - person MichaelH; 10.04.2013

Karena Anda menggunakan database sebagai objek, mengapa tidak menambahkan metode ke objek yang dapat digunakan oleh "kelas pengguna" Anda untuk menangani hal-hal yang perlu dilakukannya. Kelas pengguna dapat berisi pointer ke kelas database. Kelas database akan melindungi database Anda, dan memastikan bahwa kelas pengguna menggunakannya dengan tepat.

person WhirlWind    schedule 05.04.2010
comment
Kedengarannya seperti menggabungkan dua kelas menjadi satu. Saya lebih suka solusi yang kelasnya benar-benar independen, kecuali saya melewatkan sesuatu? - person Josh; 05.04.2010
comment
Desain OO adalah tentang enkapsulasi. Bagi saya, masuk akal untuk merangkum database secara independen, dan kemudian memiliki kelas yang mengaksesnya, sehingga hanya itu yang mengontrol akses ke database. Namun, desain lain juga dimungkinkan. Memiliki dua kelas yang mengakses database secara langsung dimungkinkan, meskipun menurut saya, hal itu menambah kompleksitas ekstra. - person WhirlWind; 05.04.2010
comment
Saya kira cara lain untuk melakukannya adalah dengan membuat instance kelas database yang terhubung ke database, kemudian menggunakan kelas terpisah untuk melakukan hal-hal pengguna melalui pegangan database yang diambil dari kelas database... Itu akan berhasil, jika Anda menginginkannya. - person WhirlWind; 05.04.2010

Berikut ini solusi menggunakan PDO.

<?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;
        }
    }
?>
person Keith Potter    schedule 12.04.2013

Saya pikir pendekatan yang lebih baik adalah dengan membuat kelas database yang langsung dibuat sendiri di database.php dan kemudian memasukkannya ke user.php. lalu setiap kali Anda membuat fungsi yang memerlukan database, Anda mengglobalkan objek database.

Periksa ini. database.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();

?>

ini pengguna.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);

}
}

?>
person user1910825    schedule 21.12.2012