Bug #11993 Updated: mysql_close closes incorrect db handler
| From: | zak@php.net | Date: | Wed, 11 Jul 2001 10:58:00 +0000 |
| Subject: | Bug #11993 Updated: mysql_close closes incorrect db handler | ||
| References: | 1 | Groups: | php.dev |
| Request: | Send a blank email to php-dev+get-59685@lists.php.net to get a copy of this message | ||
ID: 11993
Updated by: zak
Reported By: atiware@metasuccess.net
Status: Open
Bug Type: MySQL related
Operating System: Debian 2.19
PHP Version: 4.0.6
New Comment:
Here is a refinement on this bug:
Multiple duplicate calls to mysql_connect are supposed to return the same link ID. Each call after
the first call will only return the link ID of the first (if everything goes as planned, the
connection is still good, etc...).
i.e.
var_dump (mysql_connect() === mysql_connect());
Given this behavior, how should mysql_close() behave?
I would expect that calling mysql_close ($id) would close the connection that both $id and $id2
refer to.
Behavior is not this - instead it is quite odd...
Multiple calls to mysql_close are required to close multiple duplicate calls to mysql_connect.
i.e.
var_dump ($db = mysql_connect ());
var_dump ($db = mysql_connect ());
var_dump (mysql_close ($db));
// Maybe this closes the default connection?
var_dump (mysql_close ($db));
However, if more than two calls to mysql_connect are made, followed by a corresponding number of
calls to mysql_close, the mysql_close calls start to fail.
i.e.
$max = 10;
for ($x=0; $x<$max; ++$x) {
var_dump ($db = mysql_connect());
}
for ($x=0; $x<$max; ++$x) {
var_dump (mysql_close ($db));
}
Now, throw change the call to mysql_close($db) to mysql_close() - everything seems to work as
expected.
However as soon as you add a call to mysql_query after the call to mysql_close, the link will
*never* die - no matter how many times you close it.
Finally, put a call to mysql_close ($db) between the two loops. The next call to mysql_close() will
fail with an error, while subsequent calls will succeed - once again, the link will never die.
Things get even stranger when this behavior is encountered within recursive function calls -
however, I guess that this is a side effect of the behavior described above.
It looks like there is some complex/odd interactions happening with the code that closes mysql links
and the code that sets and uses the default link -- however, this is quite far over my head!
Anyone else have any ideas? :)
Previous Comments:
------------------------------------------------------------------------
[2001-07-11 05:07:29] zak@php.net
Dear Ati,
When you enter a bug report, please make the script that reproduces the error as short and simple as
possible.
I do not believe that the problem that you are encountering is a bug - you just have too many
connections open at once.
Try this script:
<pre>
<?php
error_reporting (0);
function test () {
static $count = 0;
if (++$count < 20) {
echo "Opening $count:";
var_dump ($db = mysql_connect ('localhost:3306', replace_me, replace_me));
test ();
--$count;
echo "Closing $count:";
var_dump (mysql_close ($db));
}
}
test ();
?>
</pre>
Now try it with mysql_pconnect -- does the error go away? It does for me.
In most cases, you will only need a *single* connection to a mysql database -- not multiple.
This may still be a bug - two or more calls to mysql_connect with the same arguments should only
result in one connection being opened. Each call will return the same connection ID.
------------------------------------------------------------------------
[2001-07-10 21:31:02] atiware@metasuccess.net
i have tried out with the following configurations:
server1: php-4.0.6/mysql.3.23.32/apache-1.3.20/debian 2.19
server2: php-4.0.6/mysql.3.23.37/apache-1.3.20/debian 2.19
the result is the same as with php-4.0.4pl1
please check this...
thanks
ati
------------------------------------------------------------------------
[2001-07-09 19:22:19] atiware@metasuccess.net
debian 2.19 / mysql 3.23.37 / php 4.0.4pl1
configure section of phpinfo():
'./configure' '--with-gd' '--with-jpeg-dir' '--with-png-dir'
'--with-tiff-dir' '--disable-posix' '--enable-ftp'
'--enable-calendar' '--with-imap' '--with-mcrypt'
'--with-swf=/usr/local/swf' '--with-apache=/home/atiware/apache_1.3.14'
'--enable-track-vars' '--with-mysql=/usr/local'
the sript that reproduces the problem:
--cut here--
<?php
define("DEEPLIMIT",10); //maximal deep of recursive calls
/*
!! please edit this settings !!
*/
define("MYHOST","localhost");
define("MYPORT","3306");
define("MYUSER","YOUR_USERNAME");
define("MYPWD","YOUR_PASSWORD");
/* this function reproduces the error */
function recursive($deep,$persistent=false) {
if ($deep<=DEEPLIMIT) {
//down side
if ($persistent)
$db=mysql_pconnect(MYHOST.":".MYPORT,MYUSER,MYPWD); //creating persistent mysql
connection and storing in a local variable
else
$db=mysql_connect(MYHOST.":".MYPORT,MYUSER,MYPWD); //creating mysql connection and
storing in a local variable
$res=@mysql_query("select 1 as ONE",$db); //some dummy query
$mr=null;
if (@mysql_num_rows($res)) {
$mr=@mysql_fetch_array($res);
}
//and now write the result
printf("%sRecursive: Deep: %s, DownSideQuery:
%s<br>\n",str_repeat(">",$deep),$deep,(int)$mr["ONE"]);
recursive($deep+1,$persistent);
//up side
$res=@mysql_query("select 1 as ONE",$db); //using previously created connection ($db),
if exists ;)
$mr=null;
if (@mysql_num_rows($res)) {
$mr=@mysql_fetch_array($res);
}
//write result again
printf("%sRecursive: Deep: %s, UpSideQuery:
%s",str_repeat(">",$deep),$deep,(int)$mr["ONE"]);
//error check
if (!(int)$mr["ONE"])
printf(" <b>!?ERROR!? why 0?</b>");
printf("<br>\n");
@mysql_close($db); //closing mysql connection
}
else {
printf("Limit occured (%s). Turning back...<br>\n",DEEPLIMIT);
}
}
echo "Trying with <b>mysql_connect()</b><br>\n";
recursive(1);
echo "<br><br>\n\n";
echo "Trying with <b>mysql_pconnect()</b><br>\n";
recursive(1,true);
?>
--cut here--
the output of the script:
Trying with mysql_connect()
>Recursive: Deep: 1, DownSideQuery: 1
>>Recursive: Deep: 2, DownSideQuery: 1
>>>Recursive: Deep: 3, DownSideQuery: 1
>>>>Recursive: Deep: 4, DownSideQuery: 1
>>>>>Recursive: Deep: 5, DownSideQuery: 1
>>>>>>Recursive: Deep: 6, DownSideQuery: 1
>>>>>>>Recursive: Deep: 7, DownSideQuery: 1
>>>>>>>>Recursive: Deep: 8, DownSideQuery: 1
>>>>>>>>>Recursive: Deep: 9, DownSideQuery: 1
>>>>>>>>>>Recursive: Deep: 10, DownSideQuery: 1
Limit occured (10). Turning back...
>>>>>>>>>>Recursive: Deep: 10, UpSideQuery: 1
>>>>>>>>>Recursive: Deep: 9, UpSideQuery: 1
>>>>>>>>Recursive: Deep: 8, UpSideQuery: 1
>>>>>>>Recursive: Deep: 7, UpSideQuery: 1
>>>>>>Recursive: Deep: 6, UpSideQuery: 1
>>>>>Recursive: Deep: 5, UpSideQuery: 0 !?ERROR!? why 0?
>>>>Recursive: Deep: 4, UpSideQuery: 0 !?ERROR!? why 0?
>>>Recursive: Deep: 3, UpSideQuery: 0 !?ERROR!? why 0?
>>Recursive: Deep: 2, UpSideQuery: 0 !?ERROR!? why 0?
>Recursive: Deep: 1, UpSideQuery: 0 !?ERROR!? why 0?
Trying with mysql_pconnect()
>Recursive: Deep: 1, DownSideQuery: 1
>>Recursive: Deep: 2, DownSideQuery: 1
>>>Recursive: Deep: 3, DownSideQuery: 1
>>>>Recursive: Deep: 4, DownSideQuery: 1
>>>>>Recursive: Deep: 5, DownSideQuery: 1
>>>>>>Recursive: Deep: 6, DownSideQuery: 1
>>>>>>>Recursive: Deep: 7, DownSideQuery: 1
>>>>>>>>Recursive: Deep: 8, DownSideQuery: 1
>>>>>>>>>Recursive: Deep: 9, DownSideQuery: 1
>>>>>>>>>>Recursive: Deep: 10, DownSideQuery: 1
Limit occured (10). Turning back...
>>>>>>>>>>Recursive: Deep: 10, UpSideQuery: 1
>>>>>>>>>Recursive: Deep: 9, UpSideQuery: 1
>>>>>>>>Recursive: Deep: 8, UpSideQuery: 1
>>>>>>>Recursive: Deep: 7, UpSideQuery: 1
>>>>>>Recursive: Deep: 6, UpSideQuery: 1
>>>>>Recursive: Deep: 5, UpSideQuery: 1
>>>>Recursive: Deep: 4, UpSideQuery: 1
>>>Recursive: Deep: 3, UpSideQuery: 1
>>Recursive: Deep: 2, UpSideQuery: 1
>Recursive: Deep: 1, UpSideQuery: 1
------------------------------------------------------------------------
ATTENTION! Do NOT reply to this email!
To reply, use the web interface found at http://bugs.php.net/?id=11993&edit=1