การใช้คลาสฐานข้อมูลในคลาสผู้ใช้ของฉัน

ในโปรเจ็กต์ของฉัน ฉันมีคลาสฐานข้อมูลที่ใช้จัดการข้อมูล MySQL ทั้งหมด โดยจะเชื่อมต่อกับฐานข้อมูล ดำเนินการค้นหา จับข้อผิดพลาด และปิดการเชื่อมต่อ

ตอนนี้ฉันต้องสร้างพื้นที่สมาชิกบนเว็บไซต์ของฉัน และฉันกำลังจะสร้างคลาสผู้ใช้ที่จะจัดการการลงทะเบียน การเข้าสู่ระบบ การเปลี่ยนรหัสผ่าน/ชื่อผู้ใช้/รีเซ็ต และการออกจากระบบ ในคลาสผู้ใช้นี้ ฉันต้องใช้ MySQL ด้วยเหตุผลที่ชัดเจน... ซึ่งเป็นสิ่งที่คลาสฐานข้อมูลของฉันสร้างขึ้นมาเพื่อ

แต่ฉันสับสนว่าฉันจะใช้คลาสฐานข้อมูลในคลาสผู้ใช้ของฉันอย่างไร ฉันต้องการสร้างออบเจ็กต์ฐานข้อมูลใหม่สำหรับคลาสผู้ใช้ของฉันแล้วปิดเมื่อใดก็ตามที่เมธอดในคลาสนั้นเสร็จสิ้นหรือไม่ หรือฉันจะสร้างคลาสฐานข้อมูล 'ทั่วโลก' ที่สามารถใช้ได้ตลอดทั้งสคริปต์ของฉัน (หากเป็นกรณีนี้ ฉันต้องการความช่วยเหลือ ไม่รู้ว่าต้องทำอย่างไร)

ขอบคุณสำหรับข้อเสนอแนะใด ๆ ที่คุณสามารถให้ฉัน


person Josh    schedule 05.04.2010    source แหล่งที่มา


คำตอบ (6)


กระบวนการง่ายๆ 3 ขั้นตอน 1/ สร้างวัตถุฐานข้อมูล 2/ มอบให้กับตัวสร้างคลาสผู้ใช้ของคุณ 3/ ใช้ในวิธีการของผู้ใช้

ตัวอย่างเล็กๆ น้อยๆ.

ไฟล์ Database.class.php :

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

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

ใน 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"');
  }
}

ตอนนี้ใน userManager.php เช่น:

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

หากคุณต้องการชื่อที่ทันสมัยของเทคนิคเก่านี้ Google "การพึ่งพาการฉีด" รูปแบบซิงเกิลตันใน php จะหายไปในไม่ช้า

person Arkh    schedule 07.04.2010
comment
อาจเป็นคำตอบที่ดีที่สุดที่ฉันคาดหวังได้ ตอนนี้ฉันเข้าใจสิ่งนี้ชัดเจนแล้ว ขอบคุณ :) - person Josh; 08.04.2010
comment
... แม้ว่าฉันจะไม่สามารถยอมรับคำตอบนี้โดยไม่ลงทะเบียนได้ ฮ่าๆ - person Josh; 08.04.2010
comment
นี่อาจจะนานหลายปีแล้ว แต่ขอบคุณสำหรับการโพสต์สิ่งนี้ -- มองหาไปรอบๆ มา 2 วันแล้วพยายามหาคำตอบว่าเหตุใดชั้นเรียนหนึ่งของฉันจึงไม่ดึงรหัสการเชื่อมต่อคลาส DB ของฉัน ซึ่งส่งผลให้ $this-›_link ไม่เริ่มต้น ให้ mysqli_ [blah blah] ที่จำเป็นเป็นพารามิเตอร์แรก ขอบคุณอีกครั้ง. - person MrMarlow; 11.02.2014

ดังที่เขากล่าวไว้ ให้วางฟังก์ชันทั้งหมดของคุณไว้ในคลาสฐานข้อมูลและใช้อ็อบเจ็กต์ฐานข้อมูลเพื่อเข้าถึงฟังก์ชันเหล่านั้นจากคลาสผู้ใช้ของคุณ นี่ควรเป็นวิธีที่ดีที่สุดในกรณีของคุณ เช่น:
global $database;
userclassvar = $database->doSomething();

person Joey Ezekiel    schedule 05.04.2010

สิ่งที่ฉันชอบทำคือสร้างคลาสฐานข้อมูลโดยคำนึงถึง รูปแบบซิงเกิลตัน ด้วยวิธีนี้ หากคุณมีออบเจ็กต์ฐานข้อมูลอยู่แล้ว ออบเจ็กต์ก็จะดึงข้อมูลออกมา ไม่เช่นนั้นก็สร้างออบเจ็กต์ใหม่ขึ้นมา ตัวอย่างเช่น:

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

}

และตอนนี้คุณสามารถใช้คุณสมบัติ $_link ของ User เพื่อทำฟังก์ชันฐานข้อมูลได้ เช่น $this->_link->query(...) คุณไม่จำเป็นต้องใส่ Db::getLink() ไว้ใน Constructor หากคลาสของคุณไม่จำเป็นต้องโต้ตอบกับฐานข้อมูลมากนัก

person Oliver Nagy    schedule 06.04.2010
comment
เฮ้ ฉันพยายามนำแนวคิดที่คล้ายกันไปใช้ โค้ดที่ใช้สร้างลิงก์จะเป็นอย่างไร ฉันลองใช้ self::_link = และ $this-›_link ด้วยเช่นกัน แต่ไม่อนุญาตให้ฉันตั้งค่าลิงก์ - person MichaelH; 10.04.2013

เนื่องจากคุณใช้ฐานข้อมูลเป็นวัตถุ ทำไมไม่เพียงแค่เพิ่มวิธีการให้กับวัตถุที่ "คลาสผู้ใช้" ของคุณสามารถใช้เพื่อดูแลสิ่งที่จำเป็นต้องทำ คลาสผู้ใช้สามารถมีตัวชี้ไปยังคลาสฐานข้อมูล คลาสฐานข้อมูลจะปกป้องฐานข้อมูลของคุณและรับรองว่าคลาสผู้ใช้ใช้งานอย่างเหมาะสม

person WhirlWind    schedule 05.04.2010
comment
ฟังดูคล้ายกับการผสมทั้งสองคลาสเข้าด้วยกัน ฉันต้องการวิธีแก้ปัญหาที่คลาสมีความเป็นอิสระอย่างสมบูรณ์ เว้นแต่ว่าฉันจะขาดอะไรบางอย่างไป - person Josh; 05.04.2010
comment
การออกแบบ OO เกี่ยวกับการห่อหุ้ม สำหรับฉัน มันสมเหตุสมผลแล้วที่จะห่อหุ้มฐานข้อมูลอย่างอิสระ จากนั้นให้มีคลาสที่เข้าถึงฐานข้อมูล เพื่อที่มันจะควบคุมการเข้าถึงฐานข้อมูลเพียงอย่างเดียว อย่างไรก็ตาม สามารถออกแบบอื่นๆ ได้ การมีสองชั้นที่เข้าถึงฐานข้อมูลโดยตรงเป็นไปได้ แม้ว่าความคิดเห็นของฉันจะเป็นการเพิ่มความซับซ้อนเป็นพิเศษ - person WhirlWind; 05.04.2010
comment
ฉันคิดว่าอีกวิธีหนึ่งที่สามารถทำได้คือสร้างอินสแตนซ์คลาสฐานข้อมูลที่เชื่อมต่อกับฐานข้อมูล จากนั้นใช้คลาสแยกต่างหากเพื่อทำสิ่งต่าง ๆ ของผู้ใช้ผ่านตัวจัดการฐานข้อมูลที่ดึงมาจากคลาสฐานข้อมูล... นั่นควรจะได้ผล หากคุณต้องการ - person WhirlWind; 05.04.2010

นี่คือวิธีแก้ปัญหาโดยใช้ 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

ฉันคิดว่าแนวทางที่ดีกว่าคือการสร้างคลาสฐานข้อมูลที่สร้างทันทีด้วยตัวมันเองบน Database.php แล้วรวมไว้ใน user.php ทุกครั้งที่คุณสร้างฟังก์ชันที่ต้องการฐานข้อมูล คุณจะทำให้วัตถุฐานข้อมูลเป็นแบบโกลบอลไลซ์

ตรวจสอบสิ่งนี้ 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();

?>

นี่คือ 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);

}
}

?>
person user1910825    schedule 21.12.2012