2011-06-10 24 views
4

PDOをハングアップしようとしましたが、今はあまり楽しめません。私はそれも本当に簡単なものだと思う。PDO:未定義のメソッドを呼び出すDB :: query()

編集:これを行うにはどのような方法が良いでしょうか?つまり、クラスでラッピングする代わりに?

クラス/ DB.class.php:

<?php 

// DB.class.php 

class DB { 

    protected $db_name = "PDO"; 
    protected $db_user = "root"; 
    protected $db_pass = "root"; 
    protected $db_host = "localhost"; 

    // Establish Connection to Database. 

    public function connect() { 

     try { 
      $DB = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pass); 
     } 
     catch (PDOException $e) { 
      echo $e->getMessage(); 
     } 

    } 

} 

?> 

は/ global.inc.phpが含まれています

<?php 

require_once 'classes/DB.class.php'; 

// Establish Connection to Database. 

$db = new DB(); 
$db->connect(); 

?> 

のindex.php:

<?php 

require_once 'includes/global.inc.php'; 

$STH = $db->query("SELECT * FROM users"); 
echo "<pre>"; 
print_r($STH->fetch()); 

?> 
+0

'$ db-> DB-> query()'を使う必要があります。あなたのクラスはPDOクラスを拡張していません。単純にクラスをラップしています。 –

答えて

2

あなたはしないでくださいDBクラスにはDBプロパティとquery()メソッドがあります。

class DB 
    { 
    protected $db_name = "PDO"; 
    protected $db_user = "root"; 
    protected $db_pass = "root"; 
    protected $db_host = "localhost"; 
    protected $DB = null; 

    // Establish Connection to Database. 
    public function connect() 
     { 
     try 
      { 
      $this->DB = new PDO("mysql:host=".$this->db_host.";dbname=".$this->db_name."", $this->db_user, $this->db_pass); 
      } 
     catch(PDOException $e) 
      { 
      echo $e->getMessage(); 
      } 
     } 

    public function query() 
     { 
     return $this->DB->query(); 
     } 
    } 

より良い方法は、いくつかのORMライブラリまたは裸のPDOオブジェクトを使用することです - それはかなりフレンドリーです。

+0

こんにちは、私は次のようになります:PHP致命的なエラー:行28の/Applications/MAMP/htdocs/PDO/classes/DB.class.phpの非オブジェクトのメンバ関数query()を呼び出す – ritch

+0

エラーがあったかPDOからデータベースに接続できませんでしたか? PDOオブジェクトのようなものがインスタンス化されていないようです。 –

+0

$ db_name、user、pass、hostの未定義の変数を保持していますか? – ritch

1

$ dbとしてインスタンス化されたオブジェクトにはメソッドクエリがありません。おそらく、別のオブジェクトにPDOオブジェクトをラップする必要はありませんが、そうするつもりならば、すべてのメソッドにアクセス可能であることを確認する必要があります。

+0

"PDOオブジェクトを別のオブジェクトにラップする必要はないでしょう。" - なぜそうではありませんか?私は何年もそれをしていますが、IMHOはとても便利です。 – binaryLV

+0

@binaryLV:その特定の使用例では、何もありません。継承はより良いです。しかし、抽象レイヤーを構築するときにアダプターパターンは本当に便利です。 – netcoder

1

クラスDBにはメソッドクエリがありません!あなたが新たに作成されたPDOオブジェクトにPDOがサポートするすべての機能を渡すことができます魔法の機能__call()

<?php 

    // DB.class.php 

    class DB { 

    protected $db_name = "PDO"; 
    protected $db_user = "root"; 
    protected $db_pass = "root"; 
    protected $db_host = "localhost"; 

    private $_db; 

    // Establish Connection to Database. 

    public function connect() { 

     try { 
      $this->_db = new PDO("mysql:host=".$this->db_host.";dbname=".$this->db_name, $this->db_user, $this->db_pass); 
     } 
     catch (PDOException $e) { 
      echo $e->getMessage(); 
     } 

    } 

    public function __call($name, array $arguments) { 

     if(method_exists($this->_db, $name)){ 
      try{ 
       return call_user_func_array(array(&$this->_db, $name), $arguments); 
      } 
      catch(Exception $e){ 
       throw new Exception('Database Error: "'.$name.'" does not exists'); 
      } 
     } 
    } 

} 

?> 

:あなたは、このようにそれを行うことができます。 $db_nameと、このような方法は、スコープ内で宣言されていなかったので、私は、あなたのメンバーの前で$thisキーワードを追加し、また

class DB extends PDO { 

    protected $db_name = "PDO"; 
    protected $db_user = "root"; 
    protected $db_pass = "root"; 
    protected $db_host = "localhost"; 

    public function __construct() { 
     try { 
      parent::__construct("mysql:host={$this->db_host};dbname={$this->db_name}", $this->db_user, $this->db_pass); 
     } catch (PDOException $e) { 
      echo $e->getMessage(); 
     } 
    } 

} 

$db = new DB; 
$db->query('SELECT * FROM something'); 

+0

マジックメソッドは、プログラマーのエラーを修正するための非常に悪い方法です。 –

+0

私はプログラマーのエラーを訂正したくないので、DBクラスにPDO機能を追加したいだけです。 –

+0

これは、PDOメソッドを間違って "プロキシ"を使用して呼び出すと、 "未定義の何か"のエラーが発生し、何が起こっているのかわからなくなるため、修正されません。私はあなたの答えをdownvoteするつもりはない、ちょうど、それは問題を解決するための良い方法ではないと言う。 –

2

はこれを試してみてください。

オブジェクトが作成されたときに、接続を開始したくない場合は、あなたができる:

class DB extends PDO { 

    protected $db_name = "PDO"; 
    protected $db_user = "root"; 
    protected $db_pass = "root"; 
    protected $db_host = "localhost"; 

    public function __construct() { 
     // do nothing 
    } 

    public function connect() { 
     try { 
      parent::__construct("mysql:host={$this->db_host};dbname={$this->db_name}", $this->db_user, $this->db_pass); 
     } catch (PDOException $e) { 
      echo $e->getMessage(); 
     } 
    } 

} 

$db = new DB; 
$db->connect(); 
$db->query('SELECT * FROM something'); 

重要な注意:通常、子供のメソッドをオーバーライドするとき、あなたは同じことを指定する必要がありますメソッドシグネチャを親として(またはE_STRICTエラーが発生します)。幸いにも、これはコアクラスには当てはまりません。おそらくこのようなオーバーライドを可能にするでしょう。

関連する問題