2010-04-05 16 views
7

Projemde tüm MySQL öğelerini işlemek için kullandığım bir veritabanı sınıfım var. Bir veritabanına bağlanır, sorguları çalıştırır, hataları yakalar ve bağlantıyı kapatır.Kullanıcı sınıfımda bir veritabanı sınıfı kullanma

Şimdi sitemde bir üye alan oluşturmak gerekir ve ben de, Kullanıcı adı/şifre değişikliklerini/sıfırlama yapıp çıkış yaptıktan, kayıt işlemi verecek bir kullanıcıların sınıfını inşa edecekti. Bu kullanıcı sınıfında, MySQL'i açık nedenlerle kullanmam gerekiyor ... veritabanı sınıfımın ne için yapıldığı bu.

Ancak veritabanı sınıfımı kullanıcı sınıfımda nasıl kullanacağım konusunda kafam karıştı. Kullanıcı sınıfım için yeni bir veritabanı nesnesi oluşturmak ve o sınıftaki bir yöntem bittiğinde onu kapatmak isteyebilir miyim? Ya da bir şekilde tüm senaryonun tamamında kullanılabilecek bir 'global' veritabanı sınıfı yapıyorum (eğer bu durumda yardıma ihtiyacım varsa, ne yapacağımı bilmiyorum.)

Verebileceğiniz herhangi bir geri bildirim için teşekkürler ben mi.

cevap

0

Eğer sadece "kullanıcılar sınıf" o yapması gereken şeyler dikkat çekmek için istihdam edebilirsiniz nesneye yöntemleri eklemek neden bir nesne olarak veritabanı kullanarak beri. Kullanıcı sınıfı, veritabanı sınıfına bir işaretçi içerebilir. Veritabanı sınıfı veritabanınızı koruyacak ve kullanıcıların sınıfının uygun şekilde kullanıldığından emin olacaktır. Dediği gibi

+1

Bu iki sınıfı birbirine karıştırmak gibi bir şey. Bir şeyleri kaçırmadığım sürece, sınıfların tamamen bağımsız olduğu bir çözümü tercih ederim. – Josh

+0

OO tasarımı enkapsülasyon ile ilgilidir. Bana göre, veritabanını bağımsız olarak kapsüllemek mantıklıdır ve daha sonra erişen sınıflara sahiptir, böylece veritabanına erişimi tek başına kontrol eder. Bununla birlikte, diğer tasarımlar mümkündür. Veritabanına doğrudan erişen iki sınıfın olması mümkün olsa da, benim düşüncem de ek bir karmaşıklık katıyor. – WhirlWind

+0

Bunu yapmanın başka bir yolu, veritabanına bağlanan bir veritabanı sınıfı örneğini başlatmak, sonra veritabanı sınıfından alınan bir veritabanı tanıtıcısı aracılığıyla "kullanıcı" şeyler yapmak için ayrı bir sınıf kullanmak olduğunu varsayalım. onu tercih ederim. – WhirlWind

1

, veritabanı sınıfındaki tüm işlevlerini koymak ve kullanıcı sınıfından bu işlevleri erişmek için veritabanı nesnesini kullanın. Bu sizin durumunuzda en iyi yöntem olmalı. Ör:
global $database;
userclassvar = $database->doSomething();

1

Ne yapmak ister akılda Singleton pattern ile veritabanı sınıf yapmaktır. Bu şekilde, eğer bir veritabanı nesnesine sahipseniz, sadece onu alır, aksi halde yeni bir tane oluşturur. Örneğin:

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

} 

Ve şimdi $this->_link->query(...) gibi, veritabanı fonksiyonları yapmak User 'ın $_link özelliğini kullanabilirsiniz. Sınıfınız o kadar çok veri tabanı ile etkileşime girmek zorunda değilse, kurucuya Db::getLink()'u eklemeniz gerekmez.

+0

Hey, benzer bir konsepti uygulamaya çalışıyorum, böyle bir bağlantı kurabilecek kod ne olabilir? Ben de self :: _ link = ve $ this -> _ link kullanmayı denedim, ancak bağlantıyı kurmama izin vermeyecek. – MichaelH

21

Basit, 3 adımlı işlem. 1/Veritabanı nesnesi oluşturun. 2/Kullanıcı sınıf kurucunuza verin. 3/Kullanıcı yöntemlerinde kullanın.

Küçük örnek.

Dosya Database.class.php: User.class.php yılında

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

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

:

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

Şimdi, userManager.php örneğin:

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

Eğer Bu eski tekniğin güncel moda adını, google "Bağımlılık Enjeksiyonu" istiyorum. Php'deki Singleton modeli yakında kaybolur.

+0

Muhtemelen en iyi cevap umuyordum, bunu açıkça görüyorum. Teşekkür ederim. :) – Josh

+0

... Kayıt olmadan bu cevabı kabul edememem de, lol – Josh

+4

So ... kayıt? –

0

Daha iyi bir yaklaşımın, bir veritabanı.php üzerinde hemen kendi kendine yeten veritabanı sınıfını oluşturmak ve sonra onu user.php dosyasına eklemek olacağını düşünüyorum. Daha sonra bir veritabanına ihtiyaç duyan bir işlev oluşturduğunuzda, veritabanı nesnesini küreselleştirirsiniz.

Bunu denetleyin. databse.php burada

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

?> 

İşte 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

olan PDO kullanarak bir çözümdür.

<?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; 
     } 
    } 
?> 
İlgili konular