This question already has answers here:
Check if db connection is closed - php
(4 answers)
Closed 9 years ago.
I have the following class method -
class Someclass
{
/* Other properties and methods */
public function close_connection($connection=NULL)
{
return mysql_close($connection)
}
}
Now, before calling the mysql_close function in the above code, I want to check if the $connection points to a open database connection. That is, I want to be sure that the connection I am closing is open and has not already been closed.
How can I do that?
You could try checking if your $connection variable is infact a valid resource.
<?php
if(is_resource($connection))
{
mysql_close($connection);
}
?>
Edit: Okay, this updated code now includes Gordon's suggestion.
<?php
if(is_resource($connection) && get_resource_type($connection) === 'mysql link')
{
return mysql_close($connection);
}
else
{
return false;
}
?>
You could try mysql_thread_id($connection). That'll return false if there's no usable connection.
If you have other code that could be closing the connection, have them set the connection to null so you can test for that.
If you are unsure wether the connection has been closed from the other end, due to a timeout or a network error, the only way to test it is to actually send data through using something like mysql_ping. However, this would be a terrible waste of resources if you are just trying to avoid closing a connection that might already be closed.
Note: as mentioned by evord, using mysql_ping will attempt to reopen the connection if it is no longer open.
I would use MYSQLI extension for this purpose, because this extension automatically handles all connections, and you don't need to worry but it at all. This extension is in every hosting =) For me it's a default for 4 years already =)
another way maybe is the best to handle exception for example, if dont want to use #mysql_close() then just catch exception and do nothing =) return true...
I found a good solution to be a combination of Travis and user353297's (and Gordon's) answers with a little addition of my own:
Old answer (incorrect):
if(is_resource($connection) && get_resource_type($connection) === 'mysql link')
{
if($mysqli_connection_thread = mysqli_thread_id($connection))
{
$connection->kill($mysqli_connection_thread);
}
$connection->close();
}
Edit: I found that the solution I aggregated and used before wasn't actually working properly. This was because I am using mysqli not mysql. My edited answer provides a working version of the previous code but works with the mysqli connection object (which is not, in fact, a resource).
I found the solution here: check if a variable is of type mysqli object?
New answer (and working properly for mysqli):
if(is_object($mysqli_connection) && get_class($mysqli_connection) == 'mysqli')
{
if($mysqli_connection_thread = mysqli_thread_id($connection))
{
$mysqli_connection->kill($mysqli_connection_thread);
}
$mysqli_connection->close();
}
I have created a function containing a few of these statements specific to certain database connections and I call the function at the end of every script once I am sure that I will not be using any of the connections anymore. This makes sure that the threads die, the connection closes - if it is open - and that the resources are freed up, which can become an issue if there are lots of connections to multiple DBs per user, as is my case.
Thanks a lot to Travis, user353297 and Gordon for giving me the info I needed to put this together!
just use #mysql_close($connection) to suppress errors/warnings.
Related
I've read in PDO manual that to close connection you should use the following:
$connection = null;
However, Some people suggested that since PHP 5.3 has a new GC, the following should be used:
unset($connection);
I need to know once and for all, which one is preferred, or are they the same?
They do the same thing. Unsetting the $pdo handle and setting it null both close the connection.
You can test this for yourself. Run the following script in one window, and in a second window open the MySQL client and run SHOW PROCESSLIST every couple of seconds to see when the connection disappears.
<?php
$pdo = new PDO(..);
sleep(10);
unset($pdo);
echo "pdo unset!\n";
sleep(10);
Then change unset($pdo) to $pdo=null; and run the test again.
<?php
$pdo = new PDO(..);
sleep(10);
$pdo = null;
echo "pdo set null!\n";
sleep(10);
The extra sleep() at the end is there to give you a moment to see that the connection has dropped, before the PHP script terminates (which would drop the connection anyway).
I stumbled with this. I have a PDO object that spans setup and teardown, and I can't find where there must be a remaining reference, as setting $pdo to null did not resolve the problem.
User Contributed Notes in http://php.net/manual/en/pdo.connections.php discusses the problem of delayed closure. Here they suggest killing the current connection:
$pdo->query('SELECT pg_terminate_backend(pg_backend_pid());');
$pdo = null;
This is for postgres. For mysql I have used:
$pdo->query('KILL CONNECTION CONNECTION_ID();');
using
$pdo = null; //is an assignment to null; the variable still declared in the memory.
but
unset($pdo); // will call the function to distroy also the adress "#" pointed by the variable.
so using unset is prefered.
Just don't bother with closing at all. PHP will close it for you all right.
Note that of course your application have to be sanely designed, without the need of reconnecting to different databases at a rate of machine-gun. And even in latter case, the method you are using to close would be the least problem. You are barking wrongest tree ever. Work the number of connections, not the way you are closing them.
I have a problem with reaching my connection limit too quickly... Am I right in thinking the following will help resolve this?
On older files using mysql_query
<?php
mysql_close($link);
if (isset($link2)) {
mysql_close($link2);
}
?>
On newer files using mysqli class
class DB extends MySQLi {
function __destruct() {
$this->close();
}
}
You may also be keeping connections open via persistent connections (pconnect), causing your database server to pool and stack up the connections. I've had troubles with this up until about PHP5.2?
Connection is closed automatically when script finishes it's work even if you forget to mysql_close(). Consider raising max_clients setting my.cnf
Also, if you are using only one database, you wont need, you don't need two connections - use one instead.
<?php
mysql_close($link);
if (isset($link2)) {
mysql_close($link2);
}
?>
This doesn't make any sense - if know that both variables may contain mysql connection resources then close the both!
Better yet - if your code is a mess and you can't make sense of it, then...
<?php
#mysql_close();
#mysql_close();
#mysql_close();
?>
But the only place you can sensibly put this (without analysing the code behaviour in some details - in which case you would know what resources you have open) is at the end of the script - which is where the connections get closed anyway.
Similarly, the destruct method is only called when all references to an object are deleted - this is marginally better but depending on the code structure you may get no benefit at all.
It makes far more sense to identify which URLs are taking a long time to process and trying to re-factor the code (both PHP and SQL) in these.
Do I need to explicitly kill and/or close a mysqli connection at the end of a script. At the moment, I do neither, and it works, but I don't have much load.
I've heard that there is connection pooling, and mysqli connections are re-used... do I need to close the connection then at all?
You should always close your connections at the end of the main script. If you uses some php5 and object to handle your DB just think about using __destruct() to automatically close it
http://php.net/manual/en/language.oop5.decon.php
No it is not necessary to close a mysql connection at the end of a script. PHP does it automatically.
it is not necessary but generally that's good practice. I personally, when wish to boost error-checking mechanism, you $con->close() for almost each function. e.g:
if($stmt = $db->prepare($statment))
{
if($db->bind_param($str, $param1, $param2))
{
// the rest of the code and error checking
}
else
}
$db->close();
}
}
else
{
$db->close();
}
This makes OOP necessary. Since you can simply write function doing this automatically with many other security checks added. codeIgniter as a framework has nice DB connectors whith superb security at a basic general level.
I am having trouble using the mysqli class in PHP and I haven't been able to find the answer anywhere.
In my script a class creates a mysqli connection that it uses throughout it's functions. Afterward, this script forks. The connection is used by the children as well, but I'm running into the problem of the connection being closed (MYSQL Server Has Gone Away) in the parent when the children die.
Before I switched to mysqli (was just using mysql) I simply called mysql_ping to assure that the db connection was there before performing the query in the parent process. Mysqli has a similar ping function BUT it doesn't actually reconnect if the connection is gone. I tried using the mysqli.reconnect=ON global setting with no luck (using php.ini and ini_set).
The php mysql_connect function allows you to grab an already-existing connection, so if I was using mysql instead of mysqli, I could simply reuse the connection in the child right after the process forked. BUT mysqli doesn't seem to have any such functionality...
The only thing I was able to do was call mysqli->ping() and if that returned false then reconnect to the database in the parent. This is terribly inefficient, and I would much rather figure out how to do it correctly with mysqli (and no need for manual reconnects) that having to change back to mysql..
Any suggestions?
The doc for mysqli_ping() says that if you set the global option mysqli.reconnect to 1 (in your php.ini) then mysqli_ping() will reconnect when it detects the connection has gone away.
Update: Since I answered this question in 2009, PHP has mostly moved on to use the mysqlnd driver by default instead of libmysql. As mentioned in the comment below, mysqlnd does not support the mysqli_ping() function, and the PHP developers did this intentionally, according to their "Won't Fix" answer in https://bugs.php.net/bug.php?id=52561
So there appears to be no solution for automatic reconnect in PHP anymore.
u can try something a bit different .. instead of ping .. try to send a really simple low intensity query like "select now()" and see if you get any better results.
Can't you use persistent connections? Also, is that really necessary to fork() ?
function IsConnected() {
if (empty($this->_connectionID) === FALSE && mysqli_ping($this->_connectionID) === TRUE) {
return true; // still have connect
}
$this->_connectionID = false;
return false; // lose connection
}
Use http://www.php.net/manual/en/mysqli.real-connect.php ... reinstall php and check your php.ini settings
I think you need to set mysqli.reconnect in my.cng, which is the mysql config, rather than php.ini, I couldn't manage to change reconnect via ini_set, but my sys admin did it in my.cnf.
So, tad confused that others have done it within php.ini....
$con = mysql_connect("localhost:".$LOCAL_DB_PORT, $LOCAL_DB_USER, $LOCAL_DB_PASS);
mysql_select_db("hr", $con);
mysql_query("set names utf8", $con);
while(true)
{
do_stuff($con);
sleep(50);
}
If connection timesout in 50 seconds,will $con still work?
If the connection times out, it won't work.
To answer the question from the comment, to cope with the problem, refer to php.net manual page for mysql_connect() which says:
If a second call is made to mysql_connect() with the same arguments, no new link will be established, but instead, the link identifier of the already opened link will be returned.
so if you want to make sure you always have an open connection, just try to open a new one with the same arguments after the code you substituted with sleep() is done executing.
Simple answer: why don't you try it and see?
I believe codeburger is correct: if the MySQL connection times out, then it's gone. You could use a persistent connection with mysql_pconnect. You will need to call that function after sleep each time but it will use an existing connection, saving overhead.