Dokokano.COM TOP | F/T's Labo | PHP | SptBBS | PHPBBS
PEAR DBクラスの使い方
PEAR DBクラスの使い方
(PHP4からPostgreSQLを利用する方法とヨタwith勘違い)





■ 目次

 はじめに:PHPからDBを使う
 Pearとは
 Pearの取得方法
 Pear DBクラスライブラリ

 クラス概要
 クラスリファレンス
   DB クラス
   DB_common クラス
   DB_pgsql クラス
   DB_result クラス
 エラーコード表

 使用方法:サンプル
   #01.データベースへの接続/切断
   #01.B.PostgreSQLへの接続/切断 (ネイティブ関数版)
   #02.テーブル作成
   #03.テーブルへのレコードの追加の表示

 レンタルサーバーでPearを使う場合(例外的な)
 PHPについて/メモ
 PHPに関するリンク
 参考資料(情報源)
 更新履歴
 このドキュメントについて問い合わせ/連絡先

 PHP掲示板 (ご意見、間違いの指摘はこちらへお願いします)
テキスト版はこちら

● はじめに:PHPからDBを使う

 PostgreSQLが使えるレンタルサーバに移ったので、早速PHPから使ってみようと思いましたが、生の関数をそのまま使うのも面倒です。
 そこで、DBアクセスクラスを作ろうと思いましたが、どうせ世の中にあるものをまた作るのも間抜けなので既存のクラスを利用することにしました。

PHPLib はどうかな?
 PHP3のころから便利なライブラリとして、PHPLibというのが広く使われています。
 セッションやDBアクセスを管理するクラスライブラリです。

ライブラリのダウンロードはこちらから(公式サイト)
http://phplib.netuse.de/

翻訳されたマニュアルはこちら
http://www.php.gr.jp/php/phplib/


・でも
 PHP4には Pear というものがあるのですよ。


● Pearとは

 Pearライブラリは、マニュアル(http://www.php.net/manual/ja/pear.php)によると

「PEAR は、TeXの CTAN および Perlの CPANにヒントを得たPHP拡張および PHPライブラリのコード用のコードレポジトリです。 」

 とのことで、これからはPHPのライブラリはPearを元に拡充しようということだと思います。
 Pearについては、PHPのマニュアルの一部になっていますし、PHPの方針としてはこれからはPearに違いないに違いないはずなので、Pearを使いましょう。そうしましょう。
 しかしながら、いまのところPearの利用実績はあまりないようで、情報がいまいちありません。
 特に国内ではPearに関する解説サイトが見つかりませんでした。(僕が調べた限りなのあてになりませんが)
 公式サイトのマニュアルについてもPear全体についてのコーディング規約などは載っていますが、各クラスのリファレンスは載っていません。
 どうしたものでしょう。
 もっともPearのコーディング規約で、ソースコードのコメントは「phpDoc」形式で書くことになっています。
 phpDocはjavaDocのようなものでコメントからマニュアルを生成してくれます。

phpDocの公式サイトはこちら
http://www.phpdoc.de/

 しかしながらphpDocでマニュアルにコンバートしたドキュメントがどこにもないのはどうしたことでしょう?(これも探し方が悪いだけかも)
 どちらにしても日本語でまとまった情報がないようなので、Pearを使って行くうちに分かったことを少しずつまとめていきたいと思います。
 まずはDB関連からです。

 なんとなく人柱

(PHP,PostgreSQLについてあまり経験はありませんので、おそらく、相当の間違いが含まれていると思われます。お気づきの点はご指摘下さい

● Pearの取得方法

 Pearは、PHP4がインストールされていれば一緒に入っているはずです。
 デフォルトでは「include_path」で指定されているディレクトリ「/usr/local/lib/php/」にあるようです。
 最新版は、CVSで取得するか、公式サイトからPHPのソースをダウンロードしてきて「pear」ディレクトリ以下を丸ごとコピーすればよいと思われます(自信なし)。

Latest version of PHP 4.0 Complete Source Code PHP 4.0.5 [2,621Kb] - 30 April 2001
http://www.php.net/downloads.php


● Pear DBクラスライブラリ

 データベースを操作するには、DBクラスを利用します。
 DBクラスは、PHPからSQLの各種RDBMSを統一されたインターフェースでアクセス出来るように設計されています。
 だいたい次のような処理をサポートしています。
  • DBへの接続、コネクションの管理
  • DBへSQL発行
  • SQL実行結果のResultSetの取得・管理
  • ResultSetから行フェッチ
  • トランザクション処理
  • エラーメッセージ処理
 対応しているDBは次の通りです
  • Interbase
  • Mini-SQL
  • Microsoft SQL Server
  • MySQL
  • Oracle 8 (OCI)
  • ODBC
  • PostgreSQL
  • Sybase
 もっとも、各DBによってSQLの細かい構文や利用可能なフィールドは異なりますので、複数DBに対応するのは簡単な作業ではないと思います。
 このドキュメントでは主にPostgreSQLの利用を前提にしています。



● クラス概要

┌─────┐
│DB        │
└─────┘
 DBへのコネクションを処理します。
 接続時にDBへのインターフェースクラス(query interface = DB_???)のインスタンスを生成します。
(DSN文字列に含まれている、DB種類指定をもとに生成するクラスを決定する)

 あとは、DSN文字列の解析(parse)や、エラーメッセージ処理などを受け持っています。
┌─────┐
│DB_common │
└┬────┘
  │┌─────┐
  ├┤DB_pgsql  │
  │└─────┘
  │┌─────┐
  ├┤DB_mysql  │
  │└─────┘
  │
  :
 DBへのインターフェースクラス(query interface)
 DB_Commonから派生しているクラスが、各DB毎の固有の処理を行っています。
 これらのクラスは、ユーザーは直接インスタンスを生成せずに、DBクラスのconnectメソッドにより生成します。(指定したDBのクラスのインスタンスが生成されます。たとえば、「pgsql」を指定した場合は、DB_pgsqlクラスのインスタンスが生成されます)
 クエリーの実行などは、このクラスに対しておこないます。
 クエリーの実行結果は、レコードセットクラス(DB_result)として取得できます。

┌─────┐
│DB_result │
└─────┘
 クエリーの結果(レコードセット)を保持します。
 レコード内容を取得できます。
 レコードのフィールド定義情報、レコード数などの取得も出来ます。

┌─────┐
│PEAR_Error│
└┬────┘
  │┌─────┐
  ├┤DB_Error  │
  │└─────┘
  │┌─────┐
  └┤DB_Warning│
    └─────┘
 DBクラス内で発生したエラー・ワーニングを保持します。
 DBクラスでエラーが発生した場合は、戻り値としてDB_Errorクラスのインスタンスが返ります。
 戻り値がエラーであるかどうかは、DB::isErrorメソッドで確認できます。
 ワーニングの場合も同様です。
 エラー処理については、Pearのエラー処理規約に準拠しているようなので、マニュアル参照(http://www.php.net/manual/ja/class.pear-error.php)。


● クラスリファレンス

 対象バージョン: PHP 4.0.5 (Pear ver.2)

 凡例:
 「▼」ユーザーが直接利用するメンバ
 「▽」クラス内部で利用されるメンバ
   (またはユーザーが直接利用するものもあるかもしれないが頻度が低そうなもの)

■ DB クラス

 DBへのコネクションを処理する。
 インターフェースクラスのインスタンスを生成するのが主な役割。
 DBクラスのインスタンスは生成する必要はない。メンバー関数は全てスタティック

 【メンバー変数】
     無し
 【メンバー関数】
    ▼ &connect($dsn, $options = false)
      データベースへ接続する

      引数 $dsn data source name
      $options オプション
      戻り値 インターフェースクラスのインスタンス


       $dsnで指定されたデータソース名を元にインターフェースクラスを生成し、データベースへ接続する。
       $dsnは、DSN文字列、または、項目毎の要素を持つArrayを指定できる。

       a) DSN文字列のフォーマットは次の通り(ソースからコピー)

        phptype://username:password@protocol+hostspec:110//usr/db_file.db
        phptype://username:password@hostspec/database_name
        phptype://username:password@hostspec
        phptype://username@hostspec
        phptype://hostspec/database
        phptype://hostspec
        phptype(dbsyntax)
        phptype

        例)
         pgsql://fukaya:password@tcp+db.fukaya.fs2.com:5432//fukaya
         pgsql://fukaya:password@localhost//fukaya

      • パスワードを指定していない場合は、「username:」の後に半角スペース1文字をいれるとよい
      • パラメータ名の意味は 次項「b)」を参照
      • DSN文字列の解析は、parseDSNメンバ関数を利用している

       b) dsnをArrayで指定する場合の要素は次の通り

        phptype データベース名("pgsql","mysql"など)
        dbsyntax SQLの文法 (通常はphptypeと同じ)
        protocol 接続に使用するプロトコル("tcp","unix"など)
        hostspec ホスト名 (ポートを指定する場合は、「:」で区切って指定する)
        ※ ローカルホストの場合は"localhost"と指定
        database データベース名
        ※ PostgreSQLの場合は、CreateDBコマンドで作成したDB名
        username DBへログインするユーザー名
        password パスワード


    ▼ apiVersion()
      APIバージョンを返す

      戻り値 APIバージョン (現在は 2 )


    ▼ isError($value)
      指定された変数がエラークラスであるか判定する

      引数 $value 判定対象の変数
      戻り値 判定結果(true:エラークラスである)

       DBクラス群のメンバ関数からの戻り値がエラークラス(DB_Error)であるか判定する。
       メンバ関数からの戻り値は、まずこのメソッドでエラー値であるか判定すること。

    ▼ isWarning($value)
      指定された変数がワーニングクラスであるか判定する

      引数 $value 判定対象の変数
      戻り値 判定結果(true:ワーニングクラスである)

       DBクラス群のメンバ関数からの戻り値がワーニングクラス(DB_Warning)であるか判定する。
       メンバ関数からの戻り値は、まずこのメソッドでエラー値であるか判定すること。

    ▼ errorMessage($value)
      エラーコードに対応するエラーメッセージ文字列を返す

      引数 $value エラーコード
      戻り値 エラーメッセージ(文字列)


    ▽ isManip($query)
      SQL文が、DML(データ操作言語)であるか判定する

      引数 $query 定対象のSQL文
      戻り値 判定結果(true:DMLである)

       SQL文が、DML(データ操作言語)であるか判定する。
       DML(Data Manipulation Language)とはデータを操作するステートメントのことです(INSERT,UPDATE,DELETE,REPLACEなど)。


    ▽ &factory($type)
      インターフェースクラスインターフェースを生成する

      引数 $type DB名
      戻り値 インターフェースクラスのインスタンス

       DSNで指定されたDB名を元に、適切なインターフェースクラスを生成して返すクラスファクトリー。
       たとえば、$typeに「pgsql」を渡された場合は、DB_pgsqlクラスのインスタンスを返す。
       クラス内部から利用されるユーザーが直接使用することは無い(connect関数から利用される)。

    ▽ parseDSN($dsn)
      DSN文字列を解析する

      引数 $dsn data source name
      戻り値 DNS解析結果(Array)


       $dsnで渡されたDSN文字列を解析して返す。
       引数、戻り値の形式は、connectメンバ関数の a)、b) を参照

    ▽ assertExtension($name)


■ DB_common クラス

 DBへのインターフェースクラスのベースクラス。
 各DBの固有部分を実装したクラス(DB_pgsqlクラスなど)に派生して利用し、直接は使用しない。

 DB_pgsqlクラスでオーバーライドされているメンバは、メソッド名の右に「*」を表記した。
 機能が実装されていないメソッド(DB_ERROR_NOT_CAPABLEエラーになる)は、メソッド名の右に「x」を表記した。(変な表記なので後で直す)

※ DBへの接続を終了する場合は、disconnect()メソッドを使用するが、DB_commonには存在せず、派生先のクラスにのみ存在する


 【メンバー変数】
    var $features; // assoc of capabilities for this DB implementation
    var $errorcode_map; // assoc mapping native error codes to DB ones
    var $type; // DB type (mysql, oci8, odbc etc.)
    var $prepare_tokens;
    var $prepare_types;
    var $prepare_maxstmt;
    var $error_mode = PEAR_ERROR_RETURN;
    var $error_level = E_USER_NOTICE;
    var $error_callback;
    var $last_query = '';
    var $fetchmode = DB_FETCHMODE_ORDERED;
    var $options = array(
      'persistent' => false, // persistent connection?
      'optimize' => 'performance', // 'performance' or 'portability'
    );
    var $dbh; // 選択されたインターフェースクラス(DB_pgsql等)

 【メンバー関数】
    ▽ DB_common()
      コンストラクタ

    ▽ toString()
      接続状態を文字列で返す

      戻り値 接続状態

    ▽ quoteString($string)

      SQL文の「'」を「\'」に置換する

      引数 $string 処理もとSQL文
      戻り値 置換後のSQL文

    ▽ provides($feature)
      DBの機能のインプリメント状況を取得する

      引数 $feature
      戻り値 true:インプリメントされている

      機能名
      prepare ?
      pconnect 持続的接続
      transactions トランザクション


    ▽ errorCode($nativecode)
      PHPのDB操作関数からのエラーコード(ネイティブ)を、DBクラスでのエラーコードに変換する

      引数 $nativecode エラーコード(ネイティブ)
      戻り値 DBクラスでのエラーコード

    ▽ errorMessage($dbcode)
      PHPのDB操作関数からのエラーコード(ネイティブ)から、DBクラスでのエラーメッセージ(文字列)を返す

      引数 $nativecode エラーコード(ネイティブ)
      戻り値 DBクラスでのエラーメッセージ

    ▽ &raiseError($code = DB_ERROR, $mode = false, $level = false,
    $debuginfo = false, $nativecode = false)

      エラーを発生させる

    ▽ setErrorHandling($mode, $options = false)
      エラーハンドリングを設定

    ▼ setFetchMode($fetchmode)
      デフォルトでのフェッチモードを指定

      引数 $fetchmode フェッチモード
      引数:

       フェッチモードを指定する。
       フェッチモードとは FetchRow() でレコード内のフィールドを配列で取得したときの、各要素へのアクセス方法

       フェッチモード
      DB_FETCHMODE_ORDERED フィールドにはインデックスでアクセス
      (PostgreSQLの場合 pg_fetch_row 関数を使用)
      DB_FETCHMODE_ASSOC フォールド名でもアクセスできる
      (PostgreSQLの場合 pg_fetch_array 関数を使用)
      DB_FETCHMODE_FLIPPED (指定不可)

    ▼ setOption($option, $value)
      オプション値を設定する

      引数 $option 項目名
      $value

      項目名
      persistent true or false(default)
      持続的接続をするか
      optimize performance(default) or portability
      最適化

    ▼ getOption($option)
      オプション設定値を取得する

      引数 $option 項目名
      戻り値 項目に設定されている値

    ▼ prepare($query) *x
      クエリーの連続(複数?)実行する際のクエリーを設定する

      引数 $query クエリーのSQL文

      ?よくわからない。ストアドクエリーのようなもの?
       「this is emulated.」と書いてあるので、使う必要なないのか?

    ▼ execute($stmt, $data = false) *x

      prepareで設定されたクエリーを実行する


    ▼ executeEmulateQuery($stmt, $data = false)
      prepareで設定されたクエリーを実行する


    ▼ executeMultiple( $stmt, &$data )
      prepareで設定されたクエリーを実行する


    ▽ modifyQuery($query)
      ネイティブのDBへ渡すためにSQLを修正する

      引数 $query 修正前のSQL文
      戻り値 修正後のSQL文

       いまのところ内部ではなにもしていない

    ▼ &query($query) *
      クエリー実行

      引数 $query 実行するSQL文
      戻り値 SQL文を実行した結果
      DB_resultクラス : クエリー実行結果のResultSet
      DB_OK : レコードを返さないクエリーの場合
      DB_Errorクラス : エラー発生時

       クエリーを実行して結果(ResultSet)を取得する。
       ResultSetは、DB_resultクラスとして返る。
       レコードの中身を取得するのは、DB_resultクラスのメンバ関数を利用する。

       一番基本的で重要なメソッド


    ▼ &getOne($query, $params = array())
    ▼ &getRow($query, $fetchmode = DB_FETCHMODE_DEFAULT,
    $params = array())
    ▼ &getCol($query, $col = 0, $params = array())
    ▼ &getAssoc($query, $force_array = false, $params = array())
    ▼ &getAll($query, $fetchmode = DB_FETCHMODE_DEFAULT,
    $params = array())


      ? クエリー結果を一度にArrayで取得できるらしい
        DB_resultを介さないで済むので楽かも。


    ▼ autoCommit($onoff=false) x*
      オートコミットの設定

      引数 $onoff オートコミット(true:on false:off)

       デフォルトでは、ONです。

    ▼ commit() x*
      トランザクションをコミットする

    ▼ rollback() x*
      トランザクションをロールバックする

    ▼ numRows($result) x*

      指定ResultSetの行数を取得する

      引数 $result ResultSet(ネイティブ)
      戻り値 行数

    ▼ affectedRows() x*

      変更された行数を取得する

      戻り値 行数

    ▼ errorNative() x*
      ネイティブのエラーコードを返す

      戻り値 エラーコード(ネイティブ)

    ▼ nextId($seq_name, $ondemand = true) x*
      シーケンスの次の値を取得する

      引数 $seq_name シーケンス名
      $ondemand  
      戻り値 次のシーケンス値

    ▼ createSequence($seq_name) x*
      シーケンスを作成する

      引数 $seq_name シーケンス名

    ▼ dropSequence($seq_name) x*
      シーケンスを削除する

      引数 $seq_name シーケンス名


■ DB_pgsql クラス

 DB_commonの派生クラス。
 DB_commonのメソッドをオーバーライドしてPostgreSQL依存の部分を実装しています。
 メンバー関数は、DB_pgsql独自のもののみ記載。

 引数に$resultがあるメソッドは、DB_resultクラスから利用される。(引数の意味はほとんど同じので、DB_resultの説明を参照して下さい)

 【メンバー変数】
    var $connection;     // pg_connect関数の戻り値
    var $phptype, $dbsyntax;
    var $prepare_tokens = array();
    var $prepare_types = array();
    var $transaction_opcount = 0;
    var $numrows;
    var $row;
    var $affected;
    var $autocommit = true;
    var $dsn;

 【メンバー関数】
    ▽ DB_pgsql()
      コンストラクタ

    ▽ connect($dsn, $persistent = false)
      DBへ接続する

      引数 $dsn DSN
      $persistent 持続接続するか(true:する false:しない)
      戻り値 DB_OK : 成功
      DB_Errorクラス : エラー

       DSNを元にDBへ接続する。
       DSNについては、DB::connectの説明を参照。
       DBクラスから呼ばれる。

    ▼ disconnect()
      DBへの接続を終了する

      戻り値 pg_closeの戻り値

    ▽ simpleQuery($query)
      クエリーを実行する

      引数 $query SQL文
      戻り値 PostgreSQLネイティブのResultSetのハンドルを返す

    ▽ errorCode($errormsg)
      DBネイティブのエラーメッセージをDBクラスのエラーコードに変換

      引数 $errormsg PostgreSQLのエラーメッセージ
      戻り値 DBクラスのエラーコード

    ▽ &fetchRow($result, $fetchmode = DB_FETCHMODE_DEFAULT)

    ▽ fetchInto($result, &$arr, $fetchmode = DB_FETCHMODE_DEFAULT)

    ▽ freeResult($result)

    ▽ numCols($result)


    ▽ numRows($result)

    ▽ errorNative()

      ネイティブのエラーメッセージを取得する

      戻り値 PostgreSQLのエラーメッセージ


■ DB_result クラス

 クエリー実行結果のRecordSetを保持するクラス

 【メンバー変数】
    var $dbh;
    var $result; ネイティブのResultSetハンドル

 【メンバー関数】
    ▽ DB_result(&$dbh, $result)
      コンストラクタ

      引数 &$dbh インターフェースクラス(DB_pgsql等)への参照
      $result ネイティブ関数のResultSetハンドル
      (postgreSQLの場合は、pg_exec関数の戻り値)

       DB_common::queryメソッド実行時の戻り値として、インスタンスが生成される際に呼ばれる。


    ▼ fetchRow($fetchmode = DB_FETCHMODE_DEFAULT)
      現在行を取得する

      引数 $fetchmode フェッチモード
      戻り値 array : 現在行(レコード)のフィールド値
      NULL : もう読み込むべき行がない
      DB_Eddorクラス : エラー

       現在参照している行(レコード)のフィールド値を配列(Array)として返す。
       フェッチモードにより配列のアクセス方法を指定できる。

      フェッチモード
      DB_FETCHMODE_ORDERED フィールドにはインデックスでアクセス
      (PostgreSQLの場合 pg_fetch_row 関数を使用)

      例)
      $row = fetchRow(DB_FETCHMODE_ORDERED);
      echo $row[0] . ":" .$row[1];
      DB_FETCHMODE_ASSOC フォールド名でもアクセスできる
      (PostgreSQLの場合 pg_fetch_array 関数を使用)

      例)
      $row = fetchRow(DB_FETCHMODE_ASSOC);
      echo $row["ID"] . ":" .$row["NAME"];


    ▼ fetchInto(&$arr, $fetchmode = DB_FETCHMODE_DEFAULT)
      現在行を取得する(引数で渡した配列に読み込む)

      引数 &$arr レコード読み込み先の配列(Array)
        $fetchmode フェッチモード
      戻り値 DB_OK : 現在行(レコード)の読み込み成功
      NULL : もう読み込むべき行がない
      DB_Eddorクラス : エラー

       現在参照している行(レコード)のフィールド値を指定した既存の配列(Array)に返す。
       フェッチモードにより配列のアクセス方法を指定できる。

    ▼ numCols()
      レコードの列数(フィールド数)を取得する

      戻り値 レコードの列数(フィールド数)を取得する
      DB_Eddorクラス : エラー

    ▼ numRows()

      レコードの行数(レコード数)を取得する

      戻り値 レコードの行数(フィールド数)を取得する
      DB_Eddorクラス : エラー

    ▼ free()

      RecordSetを開放する


● エラーコード表

    DB_OK
    DB_ERROR
    DB_ERROR_SYNTAX
    DB_ERROR_CONSTRAINT
    DB_ERROR_NOT_FOUND
    DB_ERROR_ALREADY_EXISTS
    DB_ERROR_UNSUPPORTED
    DB_ERROR_MISMATCH
    DB_ERROR_INVALID
    DB_ERROR_NOT_CAPABLE
    DB_ERROR_TRUNCATED
    DB_ERROR_INVALID_NUMBER
    DB_ERROR_INVALID_DATE
    DB_ERROR_DIVZERO
    DB_ERROR_NODBSELECTED
    DB_ERROR_CANNOT_CREATE
    DB_ERROR_CANNOT_DELETE
    DB_ERROR_CANNOT_DROP
    DB_ERROR_NOSUCHTABLE
    DB_ERROR_NOSUCHFIELD
    DB_ERROR_NEED_MORE_DATA
    DB_ERROR_NOT_LOCKED
    DB_ERROR_VALUE_COUNT_ON_ROW
    DB_ERROR_INVALID_DSN


● 使用方法:サンプル

 以下のサンプルは次の設定のデータベースが作成されていることを前提としています。

データベース名 : ftdemo
ユーザー名 : fukaya
パスワード : (無し)

■ #01.データベースへの接続/切断

 #01は、データベースへの接続および接続の終了のサンプルです。
 (#01Bは参考のためのネイティブの関数を使用したサンプルです)

▼ #01.PostgreSQLへの接続/切断 (Pead DBクラス版)

 実行してみる http://www.dokokano.com/php/ex_db01.php
 ソースを見る http://www.dokokano.com/php/ex_db01.phps

<?php i18n_http_output("SJIS"); ?>
<HTML>
<HEAD>
  <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
  <title>DB Exsample #01 : Connect</title>
</HEAD>
<BODY>
  <H2>DB Exsample #01 : Connect</H2>
  PostgreSQLへの接続/切断を行います。<BR>
  Pear DBクラスライブラリを使用します。<BR>
  <BR>

  <?php
    // ● Pead DBクラスライブラリをインクルード
    ini_set("include_path",ini_get("include_path"));
    require_once 'DB.php'; 

    // ● 変数セット
    // DSNを設定
    $dsn = "pgsql://fukaya: @localhost/ftdemo";
    
    // ● DBへ接続
    $db = DB::connect( $dsn );

    // エラーチェック
    if (DB::isError( $db )) {
      echo "DB接続エラー : " . DB::errorMessage( $db ) . "<BR>";
    }else{
      echo "DB接続成功 : " . $db->toString() . "<BR>";
    }

    // ● DB接続終了
    $db->disconnect();
    echo "DB接続終了<BR>"

  ?>

</BODY>
</HTML>




▼ #01B.PostgreSQLへの接続/切断 (ネイティブ関数版)

 実行してみる http://www.dokokano.com/php/ex_db01b.php
 ソースを見る http://www.dokokano.com/php/ex_db01b.phps

<?php i18n_http_output("SJIS"); ?>
<HTML>
<HEAD>
  <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
  <title>DB Exsample #01B : Connect</title>
</HEAD>
<BODY>
  <H2>DB Exsample #01B : Connect</H2>
  PostgreSQLへの接続/切断を行います。<BR>
  PostgreSQLネイティブ関数を使用します。<BR>
  <BR>

  <?php
    // ● 変数セット
    // DSNを設定    
    $dsn = "dbname=ftdemo user=fukaya password=";

    // ● DBへ接続
    $db = pg_connect( $dsn );

    // エラーチェック   
    if ($db == false) {
      echo "DB接続エラー<BR>";
    }else{
      echo "DB接続成功 : " . $db . "<BR>";
    }

    // ● DB接続終了
    pg_close($db);
    echo "DB接続終了<BR>"

  ?>

</BODY>
</HTML>





■ #02.テーブル作成

 ResultSetを返さないクエリー実行のサンプル。
 次のテーブルを作成します。
(このテーブルはサンプル#03で、アクセスログ記録に使用します)

テーブル名 : t_ex01
    フィールド 説明
    f_date varchar(20) アクセス日 YYYY/MM/DD HH:MM:SS
    f_ipadr varchar(16) IPアドレス ###.###.###.###

▼ #02.テーブル作成

 実行してみる http://www.dokokano.com/php/ex_db02.php
 ソースを見る http://www.dokokano.com/php/ex_db02.phps

<?php i18n_http_output("SJIS"); ?>
<HTML>
<HEAD>
  <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
  <title>DB Exsample #02 : Create Table</title>
</HEAD>
<BODY>
  <H2>DB Exsample #02 : Create Table</H2>
  PostgreSQLのデータベースにテーブルを作成します。<BR>
  Pear DBクラスライブラリを使用します。<BR>
  <BR>

  <?php
    // ● Pead DBクラスライブラリをインクルード
    ini_set("include_path",ini_get("include_path"));
    require_once 'DB.php'; 

    // ● 変数セット
    // DSNを設定
    $dsn = "pgsql://fukaya: @localhost/ftdemo";
    
    // ● DBへ接続
    $db = DB::connect( $dsn );

    // エラーチェック
    if (DB::isError( $db )) {
      echo "DB接続エラー : " . DB::errorMessage( $db ) . "<BR>";
    }else{
      echo "DB接続成功 : " . $db->toString() . "<BR>";
    }

    // ● テーブル作成
    // テーブル作成のSQL文
    $sql = "CREATE TABLE t_ex01 (
          f_date varchar(20),
          f_ipadr varchar(16)
        )";

    // クエリー実行
    $res = $db->query( $sql );

    // エラーチェック
    if ( $res == DB_OK ) {
      echo "テーブル作成成功<BR>";
    }else{
      echo "テーブル作成失敗 : " . DB::errorMessage( $res ) . "<BR>";
    }

    // ● DB接続終了
    $db->disconnect();
    echo "DB接続終了<BR>"

  ?>

</BODY>
</HTML>


■ #03.テーブルへのレコードの追加の表示

 #02で作成したテーブルにレコードを追加し、表示します。


▼ #03.テーブルへのレコードの追加の表示

 実行してみる http://www.dokokano.com/php/ex_db03.php
 ソースを見る http://www.dokokano.com/php/ex_db03.phps

<?php i18n_http_output("SJIS"); ?>
<HTML>
<HEAD>
  <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
  <title>DB Exsample #03 : Insert & Select</title>
</HEAD>
<BODY>
  <H2>DB Exsample #03 : Insert & Select</H2>
  テーブルをレコードを追加し内容を表示します。<BR>
  Pear DBクラスライブラリを使用します。<BR>
  <BR>

  <?php
    // ● Pead DBクラスライブラリをインクルード
    ini_set("include_path",ini_get("include_path"));
    require_once 'DB.php'; 

    // ● 変数セット
    // DSNを設定
    $dsn = "pgsql://fukaya: @localhost/ftdemo";
    
    // ● DBへ接続
    $db = DB::connect( $dsn );

    // エラーチェック
    if (DB::isError( $db )) {
      echo "DB接続エラー : " . DB::errorMessage( $db ) . "<BR>";
    }else{
      echo "DB接続成功 : " . $db->toString() . "<BR>";
    }

    // ● レコード追加
    // レコード追加のSQL文
    $sql = "INSERT INTO t_ex01 ( f_date , f_ipadr )";
    $sql .= "values (" . date("'Y/m/d H:i:s'",time()) . ",'" . getenv(REMOTE_ADDR) . "')";

    
    // クエリー実行
    $res = $db->query( $sql );

    // エラー処理 (なんか常に DB_OKなような気がする)
    if ( $res == DB_OK ) {
      echo "レコード追加成功<BR>";
    }else{
      echo "レコード追加失敗 : " . DB::errorMessage( $res ) . "<BR>";
    }

    // ● レコード内容表示
    // レコード内容表示のSQL文
    $sql = "SELECT f_date,f_ipadr FROM t_ex01 ORDER BY f_date";
        
    // クエリー実行 ($resには DB_resultが返る)
    $res = $db->query( $sql );

    // エラー処理 (どうやってもDB::isErrorがtrueにならないなあ)
    if ( !DB::isError($res) ) {
      echo "レコード検索成功<BR>\n";
    }else{
      echo "レコード検索失敗 : " . DB::errorMessage( $res ) . "<BR>";
    }

    // 取得したResultSet内容を表示
    while ($row = $res->fetchRow( DB_FETCHMODE_ASSOC ) ) {
      echo "日時:" . $row["f_date"] . " / IPアドレス:" . $row["f_ipadr"] . "<BR>\n";
    }

    
    // ResultSet開放
    $res->free();

    // ● DB接続終了
    $db->disconnect();
    echo "DB接続終了<BR>"

  ?>

</BODY>
</HTML>





● レンタルサーバーでPearを使う場合(例外的なはなし)

 普通は

require_once 'DB.php';

のように必要なクラスをインクルードすれば利用できますが、レンタルサーバによってはうまくいかない場合もあるようで

・Akira Internet Service (http://www.akira.ne.jp/)

 このサイトはここのサービスを利用しています。

 設定では、include_pathはちゃんと「.:/usr/local/lib/php」となっているののに、インクルードに先立って

ini_set("include_path",ini_get("include_path"));


と再設定しないとならない。謎

・freedom2surf (http://www.f2s.com/)

 自分のホームディレクトリ以下のファイルはアクセス出来ないようになっているようで、includeも出来ないようです。

 しかたがないので、自分のディレクトリに「pear」ディレクトリを掘ってその中にファイルをコピーして使ってます。
 インクルード前に次のような設定をしてます。

ini_set("include_path", ".:./pear" );

 まあ、この方法ならどんなサーバでも使えますね。
 しかしなにか根本的なところで間違っているような


● PHPについて/メモ

  • PearのDBクラスのネイティブのDBはMySQLらしいので、MySQL以外のDBは全機能が実装されていない場合がある
  • PostgreSQLで、DB_common::queryメソッドを実行した場合、SQL文の内容によらず常に DB_OKが返ってくるような…
  • MySQLにはSequenceが無い?ためシーケンスを操作するメソッドが用意されている。これを使った方がDB間の移植性はよくなるだろう
  • DB操作でエラーが発生した場合、PHPが勝手にエラーメッセージを吐くのは、ini_set関数で抑制でいると思うがまだ試していない
  • fetchRowしたレコードのフィールドにフィールド名でアクセスするときは、大文字/小文字区別しているので注意(PostgreSQLは常に小文字、MySQLはCreate Table時の文字)
  • 関数からグローバル変数にアクセスする場合、関数内でGLOBAL宣言しないと行けないのは納得いかない
  • クラスメンバ関数からクラスメンバ変数/関数にアクセスするときに$this->が必要なのが納得行かない
  • DreamWeaverなどのWebデザインツールで作成したHTMLに動的な処理をうめこめるのがPHPの最大の利点だ。なので echo 命令で静的なHTMLまで出力するのはいかがなものかと思う。あとでデザインの修正が大変じゃないか。
  • でもそれにこだわるとデザイン修正も大変、コーディングも大変という最低のソースになる。たとえば僕のソース
  • デザイン部分をテンプレートとして外部に追い出すのが正しいのか。でもせっかくのPHPのなんとなく手軽そうな部分がスポイルされてしまうような
  • とかいいつつFastTemplateクラスが気になる

● PHPに関するリンク

PHP公式サイト
http://www.php.net/

日本PHPユーザ会
http://www.php.gr.jp/

phpLib公式ページ
http://phplib.netuse.de/

phpDoc公式サイト
http://www.phpdoc.de/


日本PostgreSQLユーザー会
http://www.jp.postgresql.org/

● 参考資料(情報源)


PHP-jp メーリングリスト
2ちゃんねる
http://www.2ch.net/


● 更新履歴

Date       Ver. Description
---------- ---- -----------------------------
2001/06/10 0.01 公開
2001/06/16 0.02 HTML版公開

● このドキュメントについて問い合わせ/連絡先

 こちらを参照ください。


深谷 崇(F/T)
E-Mail: fukaya@dokokano.com
URL: http://www.dokokano.com/




Copyright (c) 2001 Dokokano Labo. and FUKAYA Takashi All rights reserved.