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.
Related
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.
Is there any function / global variable in PHP that returns the current state of the script (something like runnning, terminating)?
Or is the only way to set this state by making use of register_shutdown_function()?
That function looks inflexible to me as an already registered shutdown functions can be overriden with it. And the shutdown function gets executed when a user aborts the connection, which is not what I'm looking for explicitly and I don't want to introduce too many constraints.
Are there any alternatives to register_shutdown_function() available? Or if not, how to deal with the shortcomings of that function?
UPDATE
Just to clarify: I'm not looking for connection state (e.g. connection_aborted()) but for the run state of the PHP script (running, terminating). Functions to find out more about the connection state I already know of, but how about the current state of the script? Has the script already been terminated and are objects (going to be) destroyed because of that?
UPDATE2
To clarify even more, I'm still not looking for connection state but for something comparable regarding the run-state. It should work in CLI as well which does not have any connection state as there is no TCP connection related to executing the code - to better illustrate what I'm looking for.
After reading a larger part of the PHP sourcecode I came to the conclusion that even if such state(s) exist on the level of experience, they do not really exist within the interpreter in form of a flag or variable.
The code about throwing Exceptions for example decides on various variables if that is possible or not.
The answer to the question is no therefore.
The best workaround I could find so far is to have a global variable for this which is set in a registered shutdown function. But a flag from PHP seems to be not really available.
<?php
register_shutdown_function(function() {$GLOBALS['shutdown_flag']=1;});
class Test {
public function __destruct() {
isset($GLOBALS['shutdown_flag'])
&& var_dump($GLOBALS['shutdown_flag'])
;
}
}
$test = new Test;
#EOF; Script ends here.
You are looking for:
Connection_aborted();
http://it.php.net/manual/en/function.connection-aborted.php
or
Connection_status();
http://it.php.net/manual/en/function.connection-status.php
Addendum
There can't be any Terminated status, because if it's terminated you can't check its status lol
I have never made (practical) use of it myself yet, but you might be able to make use of:
http://www.php.net/manual/en/function.register-tick-function.php
Using this means you can write a file or update a db or something while script is running... i.e. write a record session/some id and a timestamp id to a file or something and check for time between execution perhaps, you could say if it's not been updated in X seconds it's still running.
But as stated PHP is stateless so it's not a notion that PHP will be aware of.
Failing this, you could set a DB field in some way when a script starts/just before it 'ends', but would place a lot of overhead really.
Is there any function / global
variable in PHP that returns the
current state of the script (something
like runnning, terminating)?
No, PHP is stateless.
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.
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.
Currently, I'm opening a database connection in my app's initialization. It's a fairly small app, PHP if that's relevant.
Should I be connecting to the database, making calls, then closing and repeating this process for each database function I write?
For example, I have the following function which grabs the $db variable from my app's initialization.
function get_all_sections()
{
global $db;
$sql = 'select * from sections';
if (!$db->executeSQL($sql, $result))
{
throw new Exception($db->getDatabaseError());
exit();
}
$sections = array();
for ($i = 0; $i < $db->numberOfRows($result); $i++)
{
$sections[] = new Section($db->fetchArray($result, MYSQLI_ASSOC));
}
return $sections;
}
Would it be better if I opened the connection then closed it after I fetched the rows? That seems like a lot of connections that are opened and closed.
If you have connection pooling on (http://en.wikipedia.org/wiki/Connection_pool) its ok to be grabbing a new connection when you need it. HOWEVER, I'd say to be in the habit of treating any resource as "limited" and if you open the db handle keep it around for as long as possible.
Connecting to the database takes a finite amount of time. It's negligible when connecting over a domain socket or named pipe, but it can be much larger if over a network connection, or worse yet, the open Internet. Leave it connected for the life of the request at least.
Use mysql_pconnect for connection pooling, and close at the end of each operation. The thread won't really close, and the thread will be re-used. This way its both safe and efficient.
Since PHP MySQL connections are fairly light-weight, you are probably OK opening and closing the connection when needed. The same is not true of other database connections, such as connecting to SQL Server, which has rather heavy connections.
In all cases, however, do whatever makes the most sense in terms of maintainability/logic/dependencies. Then, if you find you are feeling a measurable slowdown, you can optimize those areas that need the speed-boost.
When in doubt, follow the golden rule: Don't optimize prematurely.
The simplest solution would be to use mysql_pconnect() - see here
This way if the connection is already open it will use it instead of creating a new one. If it's not it will connect again