#18494 [Asn->Ana]: DB::query leaks memory
| From: | lsmith@php.net | Date: | Sun, 04 May 2003 17:16:00 +0000 |
| Subject: | #18494 [Asn->Ana]: DB::query leaks memory | ||
| References: | 1 | Groups: | php.pear.dev |
| Request: | Send a blank email to pear-dev+get-15835@lists.php.net to get a copy of this message | ||
ID: 18494
Updated by: lsmith@php.net
Reported By: sam at ananova dot com
-Status: Assigned
+Status: Analyzed
Bug Type: PEAR related
Operating System: linux redhat 7.3 up2date-ed
PHP Version: 4.2.0
Assigned To: lsmith
New Comment:
I think this is a general problem with the various methods in PEAR::DB
that prepare and execute in one go and return a result set. This way
the user never gets the prepared "id". Therefore PEAR::DB should free
these for the user (since the user can't use the id again anyways).
Like so:
733c733,735
< return $this->execute($sth, $params);
---
> $result = $this->execute($sth, $params);
> $this->freeResult($sth);
> return $result;
But somebody has to go through and probably look at every instance of
return $this->execute() where the user did not pass a prepare ID. (Did
I mention before that this is imho is abuse of prepare/execute and if
you want this sort of seperation of data and query structure you should
use a layer ontop of PEAR::DB .. my 2 cents)
Previous Comments:
------------------------------------------------------------------------
[2003-04-28 04:01:32] arnaud@php.net
changing status
------------------------------------------------------------------------
[2002-07-23 11:13:06] sam at ananova dot com
$result=$this->db->query($sql,$values);
makes use of "prepare" internally and doesn't free the results.
e.g., the following script, does one query 5 times and annother time
with different values, yet when done, diagnose() prints out that 6 lots
of prepare_tokens, prepare_types, prepare_queries were stored in the db
object!
I reckon at least they should have been destroyed when the results were
destroyed (if no results, then right away!).
<?php
include_once("DB.php");
$_db=array(
'phptype' => "pgsql",
'hostspec' => "localhost",
'database' => "*****",
'username' => "*******",
'protocol' => "unix",
'password' => "***********");
$db=DB::connect($_db);
if (DB::isError($db)) {
die("Can't connect");
}
$sql="select ?";
QUERY($db,$sql,array(1));
QUERY($db,$sql,array(1));
QUERY($db,$sql,array(1));
QUERY($db,$sql,array(1));
QUERY($db,$sql,array(1));
QUERY($db,$sql,array(2));
var_dump($db);
diagnose($db);
function diagnose(&$db) {
foreach($db as $key=>$val) if (eregi('^prepare',$key) &&
is_array($val)) {
print count($val). " of $key\n";
}
}
function QUERY(&$db,$sql,$array) {
$result=$db->query($sql,array(1));
if (DB::isError($result)) {
die ("Dead: ".$result->userinfo);
}
$numRows=$result->numRows();
if ($numRows>1) die ("Too many matches for $query,");
if ($numRows) {
$data=$result->fetchRow(DB_FETCHMODE_ASSOC);
}
if (is_object($result)) $result->free();
return $data;
}
?>
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=18494&edit=1