Behaviour of mysql_connect if called twice - php

PHP+MySQL, What would happen when calling mysql_connect twice, like that:
$link = mysql_connect($server, $user, $pass);
$link = mysql_connect($server, $user, $pass);
PHP doesn't seem to generate any notice. Is the second line ignored or the new connection is established (if so, does that auto-close the previous connection) ?
I know, those situations shouldn't happen in the first place.

I know its an old question, but i was wondering the same thing myself.
So i did a test to see if php would actually ignore one connection, or open a new connection (which would be bad as it would probably put some additional load on the database).
<?
$test1 = mysqli_connect("127.0.0.1","root","pass","test_db");
$test2 = mysqli_connect("127.0.0.1","root","pass","test_db");
print "<pre>";
print_r($test1);
print_r($test2);
print "</pre>";
?>
The above will output a [thread_id].
By comparing the two ids, i found that they were not similar, and therefore i must assume that 2 connections are now open.

I was also looking for the answer. Tnx to ComFreek I got to solve my problem. I was facing the error
mysql err 2014: Commands out of sync; you can't run this command now
which is because of executing new query in middle of fetching another one in the connection. Then I was wondering if the mysqli_connect always returns a new connection or it returns an opened one if exists. About parameter 'new_link' the documentation of the deprecated "mysql_connect" says (http://php.net/manual/en/function.mysql-connect.php) :
new_link
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. The new_link
parameter modifies this behavior and makes mysql_connect() always open
a new link, even if mysql_connect() was called before with the same
parameters. In SQL safe mode, this parameter is ignored.
but the documentation of the newer class "mysqli::__construct" says (http://php.net/manual/en/mysqli.construct.php):
Opens a connection to the MySQL Server.
which means it always returns a new connection so I checked it out and did the new query (the one in middle) with a new connection and it's fixed.

Related

PDO MySQL Connection close - unset vs null

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.

is mysql_connect in header bad practice?

I have a normal website. It uses PHP to call a MySQL table. To save on typing it out all the time, I include() a connect.php file which connects to the database for me on every page. The website keeps getting a "mysql too many connections" error. Is it a bad idea to connect at the start of a page like this?
Should I create a new connection each time a PHP script needs it, then close that connection with mysql_close after that script is done? I had avoided doing as it would add repeated lines of code to the website but I'm wondering if that's what's causing the issue?
So at the moment my code is similar to this:
<?php
include("connect.php"); //connects to database using mysql_connect() function
...
PHP script that calls mysql
...
another PHP script that calls mysql
?>
Should I change it to something like this?
<?php
mysql_connect('host', 'username', 'password');
mysql_select_db('db');
PHP code that calls mysql
mysql_close();
...
mysql_connect('host', 'username', 'password');
mysql_select_db('db');
more PHP code that calls mysql
mysql_close();
?>
You should avoid making new connections to your database, as long as possible.
Making connection to database is a slow and expensive process. Having an opened connection consume few resources.
By the way, stop using mysql_* functions. Use mysqli_* or PDO.
Should I create a new connection each time a PHP script needs it [...] ?
Yes, that makes most sense, especially if not every page needs a mysql connection.
In PHP this works by setting up the database credentials in the php.ini file and you can just call mysql_select_db and it will automatically connect to the configured database if no connection exists so far.
If you write new code, encapsulate the database connection in an object of it's own so that you can more fine-grained control when to connect to the database.
Modern frameworks like for example Silex allow you to lazy load such central components (Services), so you have configured them and can make use of them when you need them but you don't need to worry about the resources (like the connection limit in your example).
[...] close that connection with mysql_close after that script is done?
You don't need that normally because PHP does this for you.
I do not think there is anything really wrong with this style of coding. It all depends on what kind of app you are writing. Just make sure you check your scripts well and get ride of any errors, you should be fine.
This is what i usually do
<?php session_start(); include "inc/config.php";
//require_once('chartz/lib/idiorm.php');
if ($_SESSION["login1"]== "Superadmin" or $_SESSION["login1"]== "User" or $_SESSION["login1"]=="Administrator")
{
$snames = $_SESSION["name1"];
$id = $_SESSION["id1"];
$stype = $_SESSION["login1"];
$stokperm = $_SESSION['stokperm'];
$navtype = $_GET['nav'];
include("inc/ps_pagination.php");
}
else
{
header ("location: ../../../index.php");
}
?>
Am not saying its the very best way out there, we are all still learnig...
I also thing you should take the advice of blue112 very seriously. Most of my apps are writing in the old fashion way, but Use mysqli_* or PDO is the way to go.

mysql Link to server lost, unable to reconnect

I get the following error:
Link to server lost, unable to reconnect
I have a mysql daemon coded, and I use mysql_pconnect to connect to mysql but after a while, I get the following error and the daemon stops functioning properly:
Link to server lost, unable to reconnect
What I do is the following:
while(true)
{
$connect = mysql_pconnect(...);
$db = mysql_select_db(...);
}
What can I do to prevent this? I need mysql connection to stay steady for the whole duration of the daemon - which may be forever.
You have a few choices.
But just as a precursor, you should try and move away from relying on mysql_* and start using the PDO instead.
Anyway...
When you open a mysql connection, it will stay "available" until the wait timeout has expired. What you are doing is constantly creating a new connection, (also without closing the other connection). This means you will either hit the server mysql limit, or your unix box socket limit very quickly.
Wait Timeout
You should first check with your server to see what this timeout is set to.
You might want to consider increasing it in your my.cnf if it is terribly low. The default period is 28800 seconds (if I recall correctly).
You can check by issuing this query:
SHOW variables like "%wait_timeout%"
You can then change the value in your my.cnf to increase it or you can also set it using
SET ##GLOBAL.wait_timeout=288000
SELECT 1
Okay, now, with a reasonable set timeout set, the "typical" way that you can make sure that you don't get the mysql has gone away message, is to just do a SELECT 1. This will do another query and make sure that the connection is held open.
And, the benefit of using the PDO is that you can then catch PDOExceptions which might be thrown when a SELECT 1 fails.
This means, that you can then try and connect again, if an exception is thrown, and then check again. If you can't connect after that then you should probably kill your daemon.
Here is some code.... you would clearly have to make your PDO object using a valid connection string.
// $pdo holds the connection and a PDO object.
try {
$pdo->execute("SELECT 1");
} catch (PDOException $e) {
// Mysql has gone away.
$pdo = null
$pdo = new PDO( $connectionString );
echo "Mysql has gone away - But we attempted to reconnect\n";
try {
$pdo->execute("SELECT 1");
} catch (PDOException $e) {
echo "Mysql has failed twice - Kill Daemon\n";
throw($e);
}
}
This is the solution that I would probably take.
You can easily substitute the SELECT 1 with your own query that you actually want to use. This is just an example.

PHP mysqli reconnect problem

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....

Will php autoreconnect to MySQL?

$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.

Categories