[PHP-users 10691] Re: pear DBオブジェクトのセッションでの受け渡し

Shinsuke Matsui php-users@php.gr.jp
Wed, 9 Oct 2002 11:53:35 +0900


松井です。

> > Warning: pg_errormessage(): supplied argument is not a valid PostgreSQL
> > link resource in /usr/local/lib/php/DB/pgsql.php on line 412
> > 
> > という警告は出ますが、print_r()で確認したところ、問題はないようです
> DBクラスを使用したその後の動作も正常に動作していますでしょうか。
> おそらくリソースが取得できずにpg_errormessage()に辿り着き、
> 上記メッセージが表示されているのだと思います。

実際に動作を確かめてみましたら、やはりちゃんと動いていないようです。
print_r()でオブジェクトの中身だけを見て、動いていると早合点して
おりました。失礼しました。

> 単に各クラスごとに接続するDBを切り替えたいのであれば、
> DSNだけを保持しておけば良いと思いますが、いかがでしょうか。

なるほど、気付きませんでした。確かにそちらの方がシンプルですね。

> 伊藤さんがご提示された
> > 問題は、内部で持つDBのコネクションの維持の方法ですが、特殊関数__sleep,__wakeup
> > などを使ってコネクションの解放と接続をうまく作ればなんとかなるような気
> がします。
> の__wakeup関数内でDB:connect()を呼べば、リソースは取得できますが、
> セッションではdb_pgsqlクラスのインスタンスを保持しているので、
> おそらくsession_start()の前にクラスの定義が必要なのではないでしょうか。

新原さんと伊藤さんから頂いたご意見を参考にして、下記のコードを
書いてみました。動作を確認してみたところ、問題なく動いているようです。
---------------------------------------------------------------------
<?php
require_once('DB.php');
class TestDB {
  var $dsn;
  var $db;
  function TestDB($dsn) {
    $this->dsn = $dsn;
    $this->__wakeup();
  }
  function q($sql) {
    return $this->db->query($sql);
  }
  function __wakeup() {
    $this->db = DB::connect($this->dsn, true);
    if (DB::isError($db)) {
      die($db->getMessage());
    }
  }
  function __sleep() {
    if ($this->db) { 
      $this->db->disconnect(); // これは必要ないと思いますが、念のため。
    }
    return array('dsn');
  }
}
session_start();
if (!isset($_SESSION['obj'])) {
  $dsn = "pgsql://www:password@localhost/smatsui";
  $_SESSION['obj'] = new TestDB($dsn);
}
$o = $_SESSION['obj'];
$r = $o->q("select * from test");
?>                                                                                                                                   
<title>TEST</title>
<?php
foreach($r->fetchRow() as $k => $v) {
  echo $k . ":" . $v . "<BR>\n";
}
$r->free();
?>
<p><a href="<?php echo $_SERVER['PHP_SELF'] ?>">LINK</a></a>
---------------------------------------------------------------------

> 私の意見としては、DBなどシステム上の共有リソースは特定のクラスに
> 依存させるより、システム内で共有できるように実装する方が
> 望ましいと思います。

なるほど。一度、今書いているプログラムの設計を見直してみたいと思います。

貴重なアドバイスを頂きまして、どうもありがとうございました。
-- 
Shinsuke Matsui <smatsui@internet-inc.co.jp>