php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #32866 implicit (and redundant) mysql_close on mysql resource destruction
Submitted: 2005-04-28 12:26 UTC Modified: 2005-04-28 14:46 UTC
From: kevin at hatry dot com Assigned:
Status: Not a bug Package: MySQL related
PHP Version: 4.3.11 OS: windows XP + linux
Private report: No CVE-ID: None
 [2005-04-28 12:26 UTC] kevin at hatry dot com
Description:
------------
I originally posted this info on follow up of bug id 30525 but it has been reported as bogus and i dont think the problem has been fully understood.
Please *do* try to understand the problem here as there *is* one !

PHP version used :
-> php 4.3.11 on win32 with the bundled 3.23.49 mysql client
-> php 4.3.11 on linux kernel 2.4.29 with external 4.1.11 mysql client

both with apache 1.3.33 and with the cli binary.

Preface :
I *do* understand that by default MySQL connections are shared in PHP. I also note that in older versions a single mysql_close() would close all of the links but that there now appears to be reference counting before finally closing the TCP connection which is a better thing for me.

The problem is :
It seems that affecting a value or 'unset'ing a variable of type mysql resource or living the function in which the variable was created calls mysql_close on that variable (and so reduces the reference) even if a previous call was already made on that variable. So the reference count becomes wrong.

So it is very hard to keep track of the real status (connected, not connected, of type mysql, of type unknown) of a mysql resource.

The reproduce code is quite simple but is, i think, a typical way of programming : you have a function (or class) that query mysql by creating its own resource.
Normally, with this version of PHP, the call to mysql_close should not close the shared connection so the code is ok to use. But with the bug a second call to mysl_close is made when the function returns.

A last note : the same bug can be found if, instead of calling the function "do_something_in_mysql" we do $link1 = -1; after the line "mysql_close($link1);".

Thank you for your time, i hope you will see the bug this time.

Reproduce code:
---------------
<?php
$link1 = mysql_connect('localhost','root','',false);
$link2 = mysql_connect('localhost','root','',false);

echo "link1 : "; var_dump($link1);
echo "link2 : "; var_dump($link2);

do_something_in_mysql();

// here $link1 and $link2 are still usable to do
// queries which is ok for me

mysql_close($link1);

// here $link2 is no more usable to do queries
// which is *not* ok => the bug.

echo "link1 : "; var_dump($link1);
echo "link2 : "; var_dump($link2);

function do_something_in_mysql () {
 $link3 = mysql_connect('localhost','root','',false);
 echo "link3 : "; var_dump($link3);
 // do some common queries here
 mysql_close($link3);
}
?>


Expected result:
----------------
link1 : resource(4) of type (mysql link)
link2 : resource(4) of type (mysql link)
link3 : resource(4) of type (mysql link)
link1 : resource(4) of type (Unknown)
link2 : resource(4) of type (mysql link)


because $link2 has not been explicitly closed the reference count should be of 1 instead of 0 (there was 3 calls to mysql_connect and only 2 calls to mysql_close) and link2 should still be usable.

Actual result:
--------------
link1 : resource(4) of type (mysql link)
link2 : resource(4) of type (mysql link)
link3 : resource(4) of type (mysql link)
link1 : resource(4) of type (Unknown)
link2 : resource(4) of type (Unknown)


$link2 is no longer a mysql resource and the TCP connection to the mysql server is lost although there was 3 calls to mysql_connect and only 2 explicit calls to mysql_close.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2005-04-28 12:49 UTC] sniper@php.net
Change false to true in mysql_connect() and it will work like  you want it to work. Still not a bug.

 [2005-04-28 13:48 UTC] kevin at hatry dot com
thank you for your direct answer however this "solution" cannot work with a heavily loaded website as it would open too much connections on the mysql server :
for example a page called 50 times a second and opening 3 connections at a the same time means 150 connections /sec to the mysql server instead of 50 ! 
This situation is clearly one where the shared connection is useful.

i will try one last example to make sure you really know how i "want it to work", please read it through and answer the last question below, thank you.

the following script (without any function to make it clearer) :

<?php
$link1 = mysql_connect('localhost','root','',false);
$link2 = mysql_connect('localhost','root','',false);

echo "link1 : "; var_dump($link1);
echo "link2 : "; var_dump($link2);
echo 'mysql thread : '.mysql_thread_id($link2)."\n";

mysql_close($link1);

echo "-- after closing link1 :\n";
echo "link1 : "; var_dump($link1);
echo "link2 : "; var_dump($link2);
echo 'mysql thread : '.mysql_thread_id($link2)."\n";

// this query works fine and that's ok with me
mysql_query('select * from user',$link2);

$link1 = NULL;

echo "-- after link1 = NULL :\n";
echo "link1 : "; var_dump($link1);
echo "link2 : "; var_dump($link2);
echo 'mysql thread : '.mysql_thread_id($link2)."\n";

// oops $link2 is no more usable to do queries,
// that's a bug for me !
mysql_query('select * from user',$link2); // line 28

?>

generate this output :

link1 : resource(4) of type (mysql link)
link2 : resource(4) of type (mysql link)
mysql thread : 16
-- after closing link1 :
link1 : resource(4) of type (mysql link)
link2 : resource(4) of type (mysql link)
mysql thread : 16
-- after link1 = NULL :
link1 : NULL
link2 : resource(4) of type (Unknown)
Warning: mysql_thread_id(): 4 is not a valid MySQL-Link resource in ... on line 24
mysql thread : 
Warning: mysql_query(): 4 is not a valid MySQL-Link resource in ... on line 28


If you could please answer this one last question :

why does affecting "NULL" to $link1 make $link2 to become "Unkown"  ?
In other words, why don't we see this output instead :

link1 : resource(4) of type (mysql link)
link2 : resource(4) of type (mysql link)
mysql thread : 16
-- after closing link1 :
link1 : resource(4) of type (Unknown)
link2 : resource(4) of type (mysql link)
mysql thread : 16
-- after link1 = NULL :
link1 : NULL
link2 : resource(4) of type (mysql link)
mysql thread : 16


If this is a feature than it should be documented as it is not obvious that changing the value of the resource variable will close the connection, even if it has been closed before.
 [2005-04-28 14:13 UTC] georg@php.net
Please don't abuse the bug system for questions and discussions. Use PHP's mailinglists (http://www.php.net/mailing-lists.php)
 [2005-04-28 14:46 UTC] kevin at hatry dot com
i didn't think i was having a discussion just thought you hadn't seen my point and wanted to make it clear.
But if you say that it is normal that "affecting "NULL" to $link1 makes $link2 to become "Unkown"" i will not bother you anymore.

I understand that you are all very busy (as i am by the way, this problem has put me way behind schedule) and i am sorry that my feedback has made you lose your time.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Apr 18 18:01:28 2024 UTC