DBクラスの作成

データベースへの接続もクラスにしてみたいと思います。
うまく作れば、DBが変わっても他のソースに与える影響を少なくすることも
できそうです。しかし、DB用のクラスはいまだにどんな構造にするか悩みますね。

自前で作らなくてもPEARのDBクラスやdbx、PEAR::DB_DataObjectなどもあります。

とりあえず経験値を上げるということで自作してみます。

まず、接続部分をコンストラクタで切断をデストラクタで行うようにします。

<?php
class B3DB {

    private $link_id;
    private $pconnect;

    function __construct($server,$user,$password,$database,$presistency = true){

        $this->pconnect = $presistency;

        if($presistency){
            $this->link_id = mysql_pconnect($server,$user,$password);
        }
        else{
            $this->link_id = mysql_connect($server,$user,$password);
        }
        if($this->link_id){
            if($database != ""){
                $db = mysql_select_db($database,$this->link_id);
                if(!$db){
                    mysql_close($this->link_id);
                    return false;
                }
                return $this->link_id;
            }
        }
        return false;
    }
    function __destruct(){
        if($this->link_id){
            if(!$this->pconnect){
                mysql_close($this->link_id);
            }
        }
    }
}
?>

接続と切断はこれでできます。
mysql_pconnectとは、持続的接続と解説されています。(接続プール)
前もって接続したデータベースへの接続と同じ接続をする場合それを利用してくれ、
同じ接続情報がない場合新たに接続を作ります。
一般的には、接続時のオーバーヘッドが大きい場合に有効と言われています。
デストラクタでは、持続的接続の場合に切断しないようにしています。

次にクエリーを投げた後の処理です。結果セットをクラス側で持つ方法と呼び出し側で持つ方法が考えられます。
今回は、直近の結果IDのみを保持するようにします。後は、結果IDを受けて動作します。

function Query($sql){
    if($sql != ""){
        $this->result_id = mysql_query($sql, $this->link_id);
        return $this->result_id;
    }
}
function FetchRow($query_id = 0){
    if(!$query_id){
        $query_id = $this->query_result;
    }
    if($query_id){
        $row = mysql_fetch_array($query_id);
        return $row;
    }
    else{
        return false;
    }
}
function FetchDynadset($query_id = 0){
    if(!$query_id){
        $query_id = $this->query_result;
    }
    if($query_id){
        while($row = mysql_fetch_array($query_id)){
            $dynaset[] = $row;
        }
        return $dynaset;
    }
    else{
        return false;
    }
}

mysql_queryの結果IDを返すメンバ関数
1行づつフェッチするメンバ関数
クエリーの結果を全て配列で返すメンバ関数
3つのメンバ関数を実装してみました。

他にも必要なメンバ関数を追加していきます。

<?php
class B3DB {

    private $link_id;
    private $pconnect;
    private $result_id;
    private $last_error_no;
    private $last_error_msg;

    function __construct($server,$user,$password,$database,$presistency = true){

        $this->pconnect = $presistency;

        if($presistency){
            $this->link_id = mysql_pconnect($server,$user,$password);
        }
        else{
            $this->link_id = mysql_connect($server,$user,$password);
        }
        if($this->link_id){
            if($database != ""){
                $db = mysql_select_db($database,$this->link_id);
                if(!$db){
                    mysql_close($this->link_id);
                    return false;
                }
                return $this->link_id;
            }
        }
        return false;
    }
    function __destruct(){
        if($this->link_id){
            if(!$this->pconnect){
                mysql_close($this->link_id);
            }
        }
    }
    function Query($sql){
        if($sql != ""){
            $this->result_id = mysql_query($sql, $this->link_id);
            return $this->result_id;
        }
    }
    function FreeQuery($query_id = 0){

        $query_id = $this->GetQueryID($query_id);

        if ($query_id){
            mysql_free_result($query_id);
        }
        else{
            return false;
        }
        return true;
    }
    function FetchRow($query_id = 0){

        $query_id = $this->GetQueryID($query_id);

        if($query_id){
            $row = mysql_fetch_array($query_id);
            return $row;
        }
        else{
            return false;
        }
    }
    function FetchDynadset($query_id = 0){

        $query_id = $this->GetQueryID($query_id);

        if($query_id){
            while($row = mysql_fetch_array($query_id)){
                $dynaset[] = $row;
            }
            return $dynaset;
        }
        else{
            return false;
        }
    }
    function ExecuteSQL($sql){
        if($sql != ""){
            $this->result_id = mysql_query($sql, $this->link_id);
            return $this->result_id;
        }
    }
    function GetRowCount($query_id = 0)
    {
        $query_id = $this->GetQueryID($query_id);
        
        if($query_id){
            $result = mysql_num_rows($query_id);
            return $result;
        }
        else{
            return false;
        }
    }
    function GetExecRowCount()
    {
        if($this->link_id){
            $result = mysql_affected_rows($this->link_id);
            return $result;
        }
        else{
            return false;
        }
    }
    protected function GetQueryID($query_id){
        if(!$query_id){
            $id = $this->result_id;
        }
        else{
            $id = $query_id;
        }
        return $id;
    }
    function Move($query_id = 0,$rownum){

        $query_id = $this->GetQueryID($query_id);

        if($query_id){
            $result = mysql_data_seek($query_id, $rownum);
            return $result;
        }
        else{
            return false;
        }
    }
    function GetCurrentID(){
        if($this->link_id){
            $next_id = mysql_insert_id($this->link_id);
            return $next_id;
        }
        else{
            return false;
        }
    }    
    function GetLastError()
    {
        $error["code"] = mysql_errno($this->link_id);
        $error["message"] = mysql_error($this->link_id);

        return $error;
    }

}
?>

長くなりましたが、こんなところでしょうか?

MySQLの関数が多くでていますが、詳しくはphpのHelpを参照してください。
面白いのは、mysql_insert_idですね。今後使えそうです。
auto_increment属性にした項目で、直近のINSERTで生成されたIDを
取得することができます。

SELECT文で返されたレコード数を知るには、mysql_num_rowsを使用します。
INSERT,UPDATE,DELETEで変更された行数を取得するには、mysql_affected_rows
使用します。

php5からは、メンバ変数,メンバ関数にprivateやprotectedといった修飾子が
使えるようになっています。