web-dev-qa-db-ja.com

PDOクラスの拡張

以下は私がこれまでに出てきたdb接続クラスですが、PDOクラス自体を拡張することによってそれを改善するつもりです、

<?php
class database
{
    protected $connection = null;

    #make a connection
    public function __construct($hostname,$dbname,$username,$password)
    {
        try 
        {
            # MySQL with PDO_MYSQL  
            $this->connection = new PDO("mysql:Host=$hostname;dbname=$dbname", $username, $password);
            $this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
        }
        catch (PDOException $e) 
        {
            $this->connection = null;
            die($e->getMessage());
        }
    }

    #get the number of rows in a result
    public function num_rows($query)
    {
        # create a prepared statement
        $stmt = $this->connection->prepare($query);

        if($stmt) 
        {
            # execute query 
            $stmt->execute();

            return $stmt->rowCount();
        } 
        else
        {
            return self::get_error();
        }
    }

    #display error
    public function get_error() 
    {
        $this->connection->errorInfo();
    }

    # closes the database connection when object is destroyed.
    public function __destruct()
    {
        $this->connection = null;
    }
}
?>

拡張クラス、

class database extends PDO
{

    #make a connection
    public function __construct($hostname,$dbname,$username,$password)
    {
        parent::__construct($hostname,$dbname,$username,$password);

        try 
        { 
            $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
        }
        catch (PDOException $e) 
        {
            die($e->getMessage());
        }
    }

    #get the number of rows in a result
    public function num_rows($query)
    {
        # create a prepared statement
        $stmt = parent::prepare($query);

        if($stmt) 
        {
            # execute query 
            $stmt->execute();

            return $stmt->rowCount();
        } 
        else
        {
            return self::get_error();
        }
    }

    #display error
    public function get_error() 
    {
        $this->connection->errorInfo();
    }

    # closes the database connection when object is destroyed.
    public function __destruct()
    {
        $this->connection = null;
    }
}

これが私がクラスをインスタンス化する方法です、

# the Host used to access DB
define('DB_Host', 'localhost');

# the username used to access DB
define('DB_USER', 'root');

# the password for the username
define('DB_PASS', 'xxx');

# the name of your databse 
define('DB_NAME', 'db_2011'); 

include 'class_database.php';

$connection = new database(DB_Host,DB_NAME,DB_USER,DB_PASS);
$sql = "
    SELECT *
    FROM root_contacts_cfm
    ORDER BY cnt_id DESC
    ";

$connection->num_rows($sql);

しかし、この拡張pdoクラスを呼び出すと、エラーが発生します。

警告:PDO :: __construct()は、パラメーター4が配列であると想定しています。文字列はC:\ wamp\www\xx\class_database.phpのxx行にあります

致命的なエラー:行xxのC:\ wamp\www\xx\class_database.phpの非オブジェクトでメンバー関数setAttribute()を呼び出す

私はオンラインでいくつかの調査をしました、私はpdoを拡張するこの基本的な構造を見つけました、しかし私はそれを理解していません...

class myPDO extends PDO
{
   public function __construct($dsn, 
                               $username=null, 
                               $password=null, 
                               $driver_options=null)
   {
      parent::__construct($dsn, $username, $password, $driver_options);
   }

   public function query($query)
   {
      $result = parent::query($query);
      // do other stuff you want to do here, then...
      return($result);
   }
}

$dsn変数は何のためのものですか? $hostname変数を拡張pdoクラスに渡すにはどうすればよいですか?

別の質問:拡張pdoクラスでエラーを表示するためのメソッドを作成するにはどうすればよいですか?拡張pdoクラスの接続を閉じるにはどうすればよいですか?

Mysqliからpdoに移行するのはとても難しいです!

ありがとう。

12
laukok

$ dsnはデータソース名です。それはあなたのためにあなたのホスト名を処理します。あなたはそれをこのように使います:

_$dsn = 'mysql:dbname=YOUR_DB_NAME;Host=YOUR_HOSTNAME'
_

$this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);行を使用して、エラーが発生したときに発生する例外を設定しました(これは私が好きです)。したがって、拡張クラスでは、例外ハンドラーでエラーを処理できます。拡張PDOクラスにgetAssocというメソッドがある場合、次のようになります。

_/// Get an associative array of results for the sql.
public function getAssoc($sql, $params=array())
{
   try
   {
      $stmt = $this->prepare($sql);
      $params = is_array($params) ? $params : array($params);
      $stmt->execute($params);

      return $stmt->fetchAll(PDO::FETCH_ASSOC);
   }
   catch (Exception $e)
   {
      // Echo the error or Re-throw it to catch it higher up where you have more
      // information on where it occurred in your program.
      // e.g echo 'Error: ' . $e->getMessage(); 

      throw new Exception(
            __METHOD__ . 'Exception Raised for sql: ' . var_export($sql, true) .
            ' Params: ' . var_export($params, true) .
            ' Error_Info: ' . var_export($this->errorInfo(), true),
            0,
            $e);
   }
}
_
5
Paul

PDOを書き直そうとするのではなく、クラスが何をする必要があるかに集中します。私は同じ考えを持っていました。なぜなら、コードを単純化して合理化するのに、そうではないからです。 PDOと間接的にインターフェースする方法を検討するためにより多くの時間を費やすことになります。

5
graham