2012-03-15 2 views
2

PDO를 "연결"클래스와 함께 사용하는 방법을 이해하려고합니다.PDO 연결 클래스/코드 및 클래스 디자인

class db { 

    private static $dbh; 

    private function __construct(){} 
    private function __clone(){} 

    public static function connect() { 
     if(!self::$dbh){ 
      self::$dbh = new PDO("mysql:host=localhost;dbname=database", "user", "password"); 
      self::$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
     } 
     return self::$dbh; 
    } 

    final public static function __callStatic($chrMethod, $arrArguments) { 
     $dbh = self::connect(); 
     return call_user_func_array(array($dbh, $chrMethod), $arrArguments); 
    } 
} 

나는 http://php.net/manual/en/book.pdo.php에서 위의 내용을 가지고, 약간 변수를 수정하지만 난 다음이 DB 클래스 내에서 PDO 연결 개체에 연결하는 방법 궁금했다?

$dbh = new db; //intiate connection??? 

$stmt = $dbh->prepare("SELECT * FROM questions WHERE id = :id"); // or should I do db::prepare.. ??? 
$stmt->bindParam(':id', $_GET['testid'], PDO::PARAM_INT); 

if ($stmt->execute()) { 
    while ($row = $stmt->fetch()){ 
     print_r($row); 
    } 
} 

어떤 아이디어로주세요? 덕분에

+0

여기 왜 전역 정적 클래스 메서드를 사용하는지 이해하려고하지 않습니다. – hakre

답변

5

나는 다소 그럴 수 있습니다. 나는 이것이 최선의 방법인지 확실하지 않지만 그것이 나를 위해 일한다.

내 factory 클래스는 내 코드의 핵심입니다. 여기에서 나는 함께 일하는 모든 수업을 생성한다. 내 팩토리 클래스는 별도의 파일 factory.class.php에 저장됩니다.

팩토리 클래스를 가짐으로써 클래스 파일을 한 번만 포함하면됩니다. 필자가이 파일을 가지고 있지 않다면 파일을 사용할 때마다 클래스 파일을 포함시켜야합니다. 나중에 클래스 파일 이름을 업데이트해야한다면 factory 클래스 파일로만 업데이트하면됩니다.

팩토리 객체를 만드는 또 다른 이유는 DB 연결 수를 줄이는 것이 었습니다.

내가 별도의 파일로 각 클래스를 저장

공장 클래스

include_once('person.class.php'); 
include_once('tracking.class.php'); 
include_once('costAnalyzis.class.php'); 
include_once('activity.class.php'); 

class Factory { 
    function new_person_obj($id = NULL) { return new Person(Conn::get_conn(), $id); } 
    function new_tracking_obj($id = NULL) { return new Tracking(Conn::get_conn(), $id); } 
    function new_costAnalyzis_obj() { return new CostAnalyzis(Conn::get_conn()); } 
    function new_activity_obj() { return new Activity(Conn::get_conn()); } 
}  

연결 클래스

// I have this class in the same file as Factory class 
// This creates DB connection and returns any error messages 
class Conn { 
    private static $conn = NULL; 

    private function __construct() {} 

    private static function init() { 
     $conf = self::config(); 
     try { 
     self::$conn = new PDO($conf['dsn'], $conf['user'], $conf['pass'], array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")); 
     } 
     catch (PDOException $e) { 
     // We remove the username if we get [1045] Access denied 
     if (preg_match("/\b1045\b/i", $e->getMessage())) 
      echo "SQLSTATE[28000] [1045] Access denied for user 'name removed' @ 'localhost' (using password: YES)"; 
     else 
      echo $e->getMessage(); 
     } 
    } 

    public static function get_conn() { 
    if (!self::$conn) { self::init(); } 
    return self::$conn; 
    } 

    // I used to get login info from config file. Now I use Wordpress constants 
    private static function config() { 
    $conf = array(); 

    $conf['user'] = DB_USER; //$config['db_user']; 
    $conf['pass'] = DB_PASSWORD; //$config['db_password']; 
    $conf['dsn']  = 'mysql:dbname='.DB_NAME.';host='.DB_HOST; 

    return $conf; 
    } 
} 

다른 클래스는

,369 객체

다음은 수업입니다. 데이터를 사용하는 곳입니다. 제 자신의 코드에서 비즈니스 계층과 데이터 개체 계층에서 프레젠테이션을 분리하는 3 계층 아키텍처를 사용하고 있습니다.

class Person extends PersonDAO { 

    function getPersonData($id) { 
    $result = parent::getPersonData($id); 

    // Here you can work with your data. If you do not need to handle data, just return result 
    return $result; 
    } 
} 


// I only have SQL queries in this class and I only return RAW results. 
class PersonDAO { 

    // This variable is also available from you mother class Person 
    private $db; 

    // Constructor. It is automatically fired when calling the function. 
    // It must have the same name as the class - unless you define 
    // the constructor in your mother class. 
    // The &$db variable is the connection passed from the Factory class. 
    function PersonDAO (&$db) { 
     $this->db = &$db; 
    } 


    public function get_data($id) { 
    $sql ="SELECT a, b, c 
      FROM my_table 
      WHERE id = :id"; 

    $stmt = $this->db->prepare($sql); 
    $stmt->execute(array(':id'=> $id)); 
    $result = $stmt->fetchAll(PDO::FETCH_ASSOC); 

    return $result; 
    } 

    public function get_some_other_data() { 
    $sql ="SELECT a, b, c 
      FROM my_table_b"; 

    $result = $stmt->fetchAll(PDO::FETCH_ASSOC); 

    return $result;  
    } 
} 

다른 클래스에 대해서도 동일한 작업을 수행하십시오.

우리가 함께 하나 개의 파일, 공장 파일을 포함

공지 사항을 모든 퍼팅. 다른 모든 클래스 파일은 팩토리 클래스 파일에 포함됩니다. 내가 그것을 알 수있는 바와 같이

// Include factory file 
include_once('factory.class.php'); 

//Create your factory object 
$person = Factory::new_person_obj(); 

//Get person data 
$data = $person->getPersonData('12'); 

// output data 
print_r($data); 
+0

답장을 보내 주셔서 대단히 감사합니다. 내가 아닌 "개체가 아닌 개체에 대한 호출 new_obj() 멤버 함수에 ..."나는 SQL 쿼리 및 데이터베이스 정보를 업데이 트했습니다 ... 당신은 간결하게 각 부분이 무엇을 언급 할 수있을 것이라고? 미안 나는 OOP에 처음이다 ..! – Tim

+0

나는 WP도 사용하지 않고 있지만 어쨌든이 변수들을 정의했다. 또한 새 쿼리를 추가하는 방법? 고마워요 :) – Tim

+0

나는 그 같은 오류와 함께 너무했는데 ... : ( – Tim

3

, 당신은 PDO 인스턴스에 대한 게으른 로딩을 구현하는 "연결 클래스"를 갖고 싶어. 그런 다음 코드의 객체가 코드의 모든 위치에서 해당 연결에 액세스 할 수있게하여 효과적으로 싱글 톤을 만듭니다.

하지 마십시오.

응용 프로그램에서 전역 상태를 지우고 모든 DB 사용 가능 클래스가 연결 클래스의 이름과 긴밀하게 연결됩니다.

조금 다른 접근 방식을 권하고 싶습니다.이미 @Steven이 암시되었으므로, DB 연결이 필요한 객체를 생성하려면 팩토리를 사용해야합니다.

다음은 간단한 구현입니다. 이 클래스의 새로운 인스턴스를 생성합니다,

$provider = function() 
{ 
    $instance = new PDO('mysql:......'); 
    $instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
    $instance->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 
    return $instance; 
}; 

$factory = new DataMapperFactory($provider); 

지금 때마다 당신이 $factory->create('SomeClass')을 실행하고 생성자에서 적절한 DB의 연결을 제공 :

class DataMapperFactory 
{ 
    protected $provider = null; 
    protected $connection = null; 

    public function __construct(Closure $provider) 
    { 
     $this->provider = $provider; 
    } 

    public function create($name) 
    { 
     if ($this->connection === null) 
     { 
      $this->connection = call_user_func($this->provider); 
     } 
     return new $name($this->connection); 
    } 

} 

이 같이 좀 그것을 사용할 수 있습니다. 그리고 처음 실행될 때 DB에 대한 연결이 열립니다.