- PR -

PHP4+postgres で $result->close()すると結果が消える

投稿者投稿内容
tohero0987
常連さん
会議室デビュー日: 2007/05/28
投稿数: 39
投稿日時: 2007-12-26 14:12
たびたびお世話になります。

本業がPGではない為、初歩的な事かもしれませんが宜しくお願いします。

PHP4で、DBと連携したWebページを作成しております。

●質問内容
function にてDB結果セットをobjectに格納し配列としてreturnする時、
return前に $result->close() すると結果が返りません。

function getItem()
{
  $result = pg_query($this->con, "select * from Item");
  $row = 0;
  while ($data = pg_fetch_object($result, $row))
  {
    $item = new Item();
    $item->setId($data->id);
    $item->setName($data->name);
    $item->setData($data->data);
    $item_array[] = $item;
    $row++;
  }
// $result->close();
  return $item_array;
}

上記のように return $item の前にclose()すると値が戻らないので、とりあえずclose()をしていません。
特に参照渡しをしている訳でもないのに何故消えるのか良く分かりませんが、根本的に何か間違いなどあるのでしょうか。

何かコメント頂けますと幸いです。
冬寂
ぬし
会議室デビュー日: 2002/09/17
投稿数: 449
投稿日時: 2007-12-26 14:54
php4は、もう使われなくなるし使ってないのですが、本当にこれで動いているのですか?
コード:
function getItem()
{
    // $thisが不明
    $result = pg_query($this->con, "select * from Item"); 
    $row = 0; 
    while ($data = pg_fetch_object($result, $row)) 
    {
        // Itemクラスが不明
        $item = new Item();
        $item->setId($data->id); 
        $item->setName($data->name);
        $item->setData($data->data);
        // $item_arrayが不明。やるとしたらループの前で初期化する。
        $item_array[] = $item; 
        $row++; 
    } 
    // $result->close(); 
    return $item_array; 
}


〜が不明、の所でエラーが出ると思うのですが。

$result->close()で内容が初期化されてしまうという事があるとしたら、set*()で参照渡しされているという事なのでは無いかと思うので、Itemクラスについて確認してみて下さい。
(しかし、pg_fetch_object()よりpg_fetch_row()の方が、参照渡しかも?と考えなくていい分よろしいかと。)
RIN
常連さん
会議室デビュー日: 2006/10/11
投稿数: 21
投稿日時: 2007-12-26 15:08
linuxと無関係のようですが、、、

pg_fetch_objectであれば、参照型だと思います。(objectですから)
下記の問題は、クローズ方法の問題かと思います。
下記修正した内容ですが、確認してみてください。
function getItem()
{
  $result = pg_query($this->con, "select * from Item");
  $row = 0;
  while ($data = pg_fetch_object($result, $row))
  {
    $item = new Item();
    $item->setId($data->id);
    $item->setName($data->name);
    $item->setData($data->data);
    $item_array[] = $item;
    $row++;
  }
// $result->close();
  pg_free_result($result);
  pg_close($this->con);
  return $item_array;
}
tohero0987
常連さん
会議室デビュー日: 2007/05/28
投稿数: 39
投稿日時: 2007-12-26 15:17
冬寂様、RIN様

コメント有難うございます。
php4は既存環境に合わせる必要がございまして旧Verを使用しております。
$item_arrayはwhileの前で、$item_array = array(); としておりましたが今は外してしまってました。

Itemクラスの方では、

class Item {
 var $id;
 var $name;
 var $data;

 function getId() {
  return $this->id;
 }
 function setId($id) {
  $this->id = $id;
 }
:

}

のように書いています。
pg_fetch_rowでも結果は同じで、pg_fetch_objectを使用してみた次第ですが、結局同じでした。

pg_free_resultも試してみたいと思います。$result->close() と同意でしょうか。
※ちなみにconnectionクローズは、別functionで作成しており、そのfunctionを上位クラスから呼んでおります。

ちなみに $result->close() しないとメモリを食いつぶしたりするものでしょうか。

[ メッセージ編集済み 編集者: tohero0987 編集日時 2007-12-26 15:21 ]
冬寂
ぬし
会議室デビュー日: 2002/09/17
投稿数: 449
投稿日時: 2007-12-26 16:46
outch!
試してみて気づいたけど、pg_fetch_object()でクラスを指定していないと(close()メソッドを実装したクラスを指定していないと)、$result->close()でエラーが起きて落ちるかもしれませんね。
ひょっとして「close()すると消える」とは、その事を言っていませんか?

>$result->close() しないとメモリを食いつぶしたりするものでしょうか
普通の設定、普通に扱う量のデータでは、一回一回のリクエストの度に自動的にクローズされるので心配ないはずです。
(でも、特に問題なければ、開いたら閉じる、というコーディングを癖にしておいた方がいいですね。)
tohero0987
常連さん
会議室デビュー日: 2007/05/28
投稿数: 39
投稿日時: 2007-12-26 20:27
冬寂様

アドバイス有難うございます。
これだ、と思いました。調べて以下のようにItemクラスを指定してみました。

while ($data = pg_fetch_object($result, $row, Item))

※残念ながら class_name の指定はPHP5からのようでした。駄目でした。

しかし、pg_fetch_object からの $data がインスタンス化されていないのかもしれませんが、それ以下で new Item でインスタンス化したものにコピーしているので、何故消えるか??です。
そういえばPHPの変数コピーの保持の仕方は、特殊らしく(詳細説明のあるHPを見ました。zvalとか)このケースではバグでコピーしたものも一緒に削除されてしまっている?などとも思ったりします。

[ メッセージ編集済み 編集者: tohero0987 編集日時 2007-12-26 20:34 ]
shimix
ぬし
会議室デビュー日: 2004/08/05
投稿数: 512
お住まい・勤務地: 大分市
投稿日時: 2007-12-26 20:42
引用:

tohero0987さんの書き込み (2007-12-26 20:27) より:
これだ、と思いました。調べて以下のようにItemクラスを指定してみました。

while ($data = pg_fetch_object($result, $row, Item))

※残念ながら class_name の指定はPHP5からのようでした。駄目でした。

しかし、pg_fetch_object からの $data がインスタンス化されていないのかもしれませんが、それ以下で new Item でインスタンス化したものにコピーしているので、何故消えるか??です。



#$dataとか$itemはとりあえず今現在の問題とは無関係だと思います。

$resultはpg_queryの戻り値ですから「resource」ですよね?それなのに$result->close()などと書いて大丈夫なんですか?・・という話だと思いますけど。

http://jp.php.net/manual/ja/function.pg-query.php

何かエラー表示の抑制をされていますでしょうか?そうであれば、エラー表示をするように設定してみることをお勧めします。

http://jp.php.net/manual/ja/function.error-reporting.php

pg_free_result($result)が$result->close()と同値かどうかという以前に「$result->close()って一体何?」ということです。

[ メッセージ編集済み 編集者: shimix 編集日時 2007-12-26 20:47 ]
tohero0987
常連さん
会議室デビュー日: 2007/05/28
投稿数: 39
投稿日時: 2007-12-26 21:06
shimix様

コメントありがとうございます。
$result->close()、ですが安易に@ITのDAOのサンプルを真似しておりました。
もう少し調べてみたいと思います。

スキルアップ/キャリアアップ(JOB@IT)