2012-02-18 16 views
3

申し訳ありませんが、私はブラジル人です。 行きましょう。シングルトンPDOモデル - 階層

class DataBase extends PDO 
{ 

/** 
* @var object PDO 
*/ 
private static $instance; 


/** 
* Cria uma instância do PDO representando a conexão ao banco de dados e torna a instância disponível como "singleton" 
* 
* @param string $dsn   O DSN completo, ex.: mysql:host=localhost;dbname=testdb 
* @param string $username  O nome de usuário para a string DSN. Esse parâmetro é opcional para alguns drivers do PDO. 
* @param string $password  A senha para a string DSN. Esse parâmetro é opcional para alguns drivers do PDO. 
* @param array $driver_options Um array key => value de opções de conexão específicas do driver 
* 
* @return PDO 
*/ 
public 
function __construct() 
{ 

    global $config; 

    $dsn  = "mysql:dbname={$config['database'][AMBIENTE]['banco']};host={$config['database'][AMBIENTE]['url']}"; 
    $username = $config['database'][AMBIENTE]['usuario']; 
    $password = $config['database'][AMBIENTE]['senha']; 

    if (!isset (self::$instance)) 
    { 
     try 
     { 
      self::$instance = parent::__construct($dsn , $username , $password); 
     } 
     catch (PDOException $e) 
     { 
      Functions::Log('Erro de conexão de banco de dados: ' . $e->getMessage()); 
      header('HTTP/1.1 500 Internal Server Error'); 
     } 
    } 

    $this->storage = new ArrayObject(); 

} 

public static 
function getInstance() 
{ 
    if (!self::$instance) 
    { 
     self::$instance = new DataBase; 
    } 

    return self::$instance; 
} 

} 

とクラスのデータベースを拡張したモデル::

class Model extends DataBase 
{ 
protected $TABLE_NAME; 
protected $TABLE_PREFIX; 
/* all logic here, like getters, setters and methods like update, delete and insert... */ 
} 

しかし、私は、クエリのようなPDOのメソッドにアクセスするか、または準備する$この変数を使用することはできません私はこれを持っています。 ModelクラスのコンストラクタがgetInstanceを呼び出しても、私はPDOコンストラクタと呼ばれていません。

可能でしょうか?

+0

なぜデータベースコンストラクタは公開されていますか? – busypeoples

+0

check self :: $ instance。これがあなたの問題です。コード例が必要な場合はお知らせください。 – busypeoples

+0

@busypeoples私のエラーを啓発できますか?私はすべての魔法の方法がデフォルトで公開されるべきだと思った。私は例を持っていたいと思います! –

答えて

2

あなたのサンプルをうまく機能させるには、これを試してみてください。

define('DB_CONN','mysql:dbname=;host='); 
define('DB_USER', ''); 
define('DB_PASS', ''); 

interface iMySQL 
{ 

    public 
    function query($string); 

    public 
    function select(); 

    public 
    function selectAll(); 

    public 
    function insert(); 

    public 
    function update(); 

    public 
    function delete(); 

    public 
    function load(); 

} 



class DataBase 
{ 

    /** 
    * @var object PDO 
    */ 
    private static $instance = null; 


    /** 
    * Cria uma instância do PDO representando a conexão ao banco de dados e torna a instância disponível como "singleton" 
    * 
    * @param string $dsn   O DSN completo, ex.: mysql:host=localhost;dbname=testdb 
    * @param string $username  O nome de usuário para a string DSN. Esse parâmetro é opcional para alguns drivers do PDO. 
    * @param string $password  A senha para a string DSN. Esse parâmetro é opcional para alguns drivers do PDO. 
    * @param array $driver_options Um array key => value de opções de conexão específicas do driver 
    * 
    */ 
    private function __construct() { 

    } 

    public static function getInstance() 
    { 
     if (self::$instance === null) 
     { 
      self::$instance = new PDO(DB_CONN, DB_USER, DB_PASS); 
     } 
     return self::$instance; 
    } 

} 

class Model 
{ 
    protected $TABLE_NAME; 
    protected $TABLE_PREFIX; 
    protected $clausula; 

    private $storage; 

    /** 
    * Recupera um registro utilizando sua chave 
    * 
    * @param string $key 
    * 
    * @return mixed O valor armazenado 
    * @throws RuntimeException Se não houver um registro para a chave especificada 
    */ 
    public 
    function __get($key) 
    { 

    } 

    /** 
    * Registra um valor à uma chave 
    * 
    * @param string $key A chave que será utilizada no registro 
    * @param mixed $value O valor que será registrado 
    * 
    * @throws LogicException Se a chave já estiver registrada 
    */ 
    public 
    function __set($key , $value) 
    { 
     //echo $key; 
    } 


    public static 
    function __callStatic($method , $args) 
    { 

     $database = DataBase::getInstance(); 
     $callback = array($database , $method); 
     return call_user_func_array($callback , $args); 

    } 

    public 
    function __call($method , $args) 
    { 

     $database = DataBase::getInstance(); 
     $callback = array($database , $method); 
     return call_user_func_array($callback , $args); 

    } 

    public function __construct($table_name = null , $id = null) 
    { 

     $this->TABLE_PREFIX = $this->config['database']['table_prefix']; 
     $this->TABLE_NAME = $this->TABLE_PREFIX . $table_name; 

     $this->storage = new ArrayObject(); 

     if (!is_null($table_name)) 
     { 
      $array = $this->query("SHOW COLUMNS FROM `$this->TABLE_NAME`")->fetchAll(); 

      $colunas  = array(); 
      $obrigatorias = array(); 

      foreach ($array as $value) 
      { 
       $colunas[] = $value[0]; 
       if ($value['Null'] === 'NO') 
       { 
        $obrigatorias[] = $value['Field']; 
       } 
      } 

      $this->colunas  = $colunas; 
      $this->obrigatorias = $obrigatorias; 
      $this->total_colunas = count($this->colunas); 

      // Se passou um id por parâmetro, salva nas propriedades do objeto 
      if (!is_null($id) AND is_numeric($id)) 
      { 
       $this->id = $id; 

       // E já carrega o objeto 
       $select = $this->query('SELECT * FROM {tabela_nome} WHERE `id` = ' . $id)->fetchObject(); 
       $this->load($select); 
      } 
     } 

    } 

    public 
    function insert() 
    { 
    } 

    public 
    function update() 
    { 
    } 

    public 
    function delete() 
    { 
    } 

    public 
    function select($clausula = NULL , $is_array = FALSE) 
    { 
     // Caso seja passado uma cláusula diretamente para a função, executa ela 
     if (!is_null($clausula)) 
     { 
      $this->clausula = $clausula; 
     } 

     // Troca uma possível variável pelo nome da tabela do Model 
     $this->clausula = (str_replace('{TABLE_NAME}' , $this->TABLE_NAME , $this->clausula)); 
     $this->clausula = (str_replace('{TABLE_PREFIX}' , $this->TABLE_PREFIX , $this->clausula)); 

     // Executa o SELECT no banco de dados 
     $query = $this->query($this->clausula); 

     if ($query AND $query->rowCount() > 0) 
     { 

      if ($query->rowCount() == 1 AND !$is_array) 
      { 
       return $query->fetchObject(get_class($this)); 
      } 
      else 
      { 
       $objetos = array(); 
       while ($linha = $query->fetchObject(get_class($this))) 
       { 
        $objetos[] = $linha; 
       } 
       return (count($objetos) > 0) ? $objetos : FALSE; 
      } 
     } 
     else 
     { 
      return FALSE; 
     } 
    } 

    public 
    function selectAll() 
    { 
    } 

    public 
    function load() 
    { 
    } 
} 



$model = new Model(); 
$stmt = $model->query(); 
$fetch = $stmt->fetchAll(); 
var_dump($fetch); 

これはテストされていません。しかし、それはあなたに問題を解決する方法を与える必要があります。 この方法をお試しください。

define('DB_TYPE', 'DB_Class_One'); 


class DB_Class_One extends PDO { 
    public function getData() { 
     print 'Class One'; 
    } 
} 

class DB_Class_Two extends PDO { 
    public function getData() { 
     print 'Class Two'; 
    } 
} 

class DB_Class_Three extends PDO { 
    public function getData() { 
     print 'Class Three'; 
    } 
} 

class DataBase { 

    private static $instance = null; 

    private function __construct() { 

    } 

    private function __clone() { 

    } 

    public static function getInstance() { 
     $class = DB_TYPE; 

     if (self::$instance === null) { 
      self::$instance = new $class("mysql:host=;dbname=", '', ''); 
     } 
     return self::$instance; 
    } 


} 




$db = DataBase::getInstance(); 

$stmt = $db->query(); 

$result = $stmt->fetch(); 

$db->getData(); 
+0

を試してみます。パラメータ1が有効なコールバックになるため、クラス 'DataBase'には 'query' "というメソッドはありません。 フルコードは次のとおりです。http://pastebin.com/BwPvh3mV​​ –

+0

コアクラスを拡張しないでください。クラスを可能な限り独立させてみてください。レジストリを作成し、すべてのコア変数を追加します。または、設定ファイルを作成し、define()を使用してすべての設定データを設定します。あなたは上記のアプローチを試しましたか?私は今それをテストした、それは動作します。 – busypeoples

+0

あなたは@busypeoplesを困らせて申し訳ありません。私はまだ$ this->メソッドを使用することはできません私のモデルでは、それを拡張するか、またはDataBaseクラスではありません。 私に合ったクラスを書くことができますか?私はあなたのためにPayPalを介して支払いを行うことができます。 –

0

何かがあなたのgetInstance()方法について面白いようだとあなたのコンストラクタは、両方のself::$instanceに割り当てる:

function getInstance() 
{ 
    if (!self::$instance) 
    { 
     self::$instance = new DataBase; 
    } 

/* .... */ 

function __construct() 
{ 

/* .... */ 

    if (!isset (self::$instance)) 
    { 
     try 
     { 
      self::$instance = parent::__construct($dsn , $username , $password); 
     } 

getInstance()から割り当てを削除し、それが動作するかどうかを確認します。

+0

これはシングルトンのPDOラッパーです。私はこのDataBaseクラスを拡張するだけでモデルを使うことができると思ったが、うまくいかなかった。この時点での最善のアプローチは、__callを使用して、PDOインスタンスが格納されている$ instanceプロパティにコールを転送することです。しかし、$ this-> query()は機能しません。 –

+0

私のモデルクラスを完成させてPDOだと思うようにIDEを偽装する方法はありますか?モデルクラス$ this-> que(popup query)を使用したいと思います。 –

+0

申し訳ありませんが、私の選択したエディタ 'vim'にオートコンプリートビットを設定しても構いません。 – sarnold