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.
Related
I have been trying to serialize phpseclib connection since I am loading some php pages from ajax and I dont want to reconnect again and again.
Page 1 - define SSH2 First
require("Net/SSH2.php");
session_start();
$ssh = new Net_SSH2 ("localhost");
if ($ssh->login($username, $pass)) {
$_SESSION['obj'] = serialize($ssh);
}else{
echo "Invalid Login !!!";
}
Page 2 - Get Stored session with unserialize
session_start();
require("Net/SSH2.php");
$ssh = unserialize($_SESSION['obj']);
echo $ssh->exec('ls');
I want to put Login information in $_SESSION['obj'] too so Whenever I am on that php page i just $ssh = unserialize($_SESSION['obj']); and then $ssh->exec('pwd') ..
Is there work around or will I have to always connect/login to Net/SSH2.php whenever I am on that PHP page ???
Depending on which PHP version you have, you could try to declare a static variable for the ssh connection.
If phpseclib uses pfsockopen it might be able to reuse existing connections - but that is a longshot, and might require modification of the library.
But generally speaking you cannot do what you want in PHP. When the script is finished all open sockets are closed, as the executing process terminates.
You certainly can't store it in a session variable - as soon as the Net_SSH2 object goes out of scope it is destroyed.
The only way to have a persistent connection is to actually have a script constantly running which is keeping the connection open. Which means you have one script with a never ending while (true) { ... } loop which opens a connection once and keeps it. You then need to find a way to communicate with this script to make it execute commands. AMQP, ØMQ, Gearman, sockets and similar techniques can be employed for that.
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.
I am creating a simple Web Application in PHP for my college project. I am using the MySQL database.
I connect to the database in login.php. After connection I assign the connection to $_SESSION["conn"] and then redirect to main.php.
In main.php I write $conn = $_SESSION["conn"]. But the connection in $conn does not work.
I thought that as the login.php script ends, the connection gets closed. So I tried using mysql_pconnect instead of mysql_connect but that too does not work.
I know I can reconnect to the database in every PHP file. But I don't want to do this. I want to use the same connection in all PHP files.
Instead of saving the DB connection in a session you should make the connection calls in a separate file such as db.php and then require it from each of your scripts. For example, place your connection in db.php:
mysql_connect('...', '...', '...');
mysql_select_db('...');
and then bring it in in login.php:
require('db.php');
$res = mysql_query('...');
You can then do the same for each PHP file that needs access to the DB and you'll only ever have to change your DB access credentials in one file.
After connection I assign the connection to $_SESSION["conn"] and then redirect to main.php.
You'll probably want to read up on PHP sessions. You can't store resources (database connections, file handles, etc) in a session, because they can not be serialized and stored.
Keep in mind that each and every visit to a PHP script invokes a new instance of the PHP interpreter (via CGI, via FastCGI, or via a built-in module), and invokes a new instance of the script. Nothing is shared between script calls, because the entire environment goes away when the script exits.
The other answers are correct -- you'll need to connect to the database on every script call. Place the connection in a common include file for convenience.
The second request may not be served by the same web server process as the first, which means that you will have a completely separate set of database resources. You'll need to connect again in this new process in order to run queries.
What I normally have is a Connection class that pages will require in order to establish a connection. Something along the lines of:
class Connection {
public $dbConnection = null;
public $isConnectionActive = false;
private $dbServer = null;
private $dbCatalog = null;
private $dbUser = null;
private $dbPassword = null;
}
This class handles opening and closing of the connection on any pages.
It sounds that you want to make your php connections persistants , in that way and if it is so , then you have to create a PDO Object with the required parameters to create a new PHP PDO Object that will attempt to connect to mysql , and in the object instanciation , try to pass persistancy option value to true , you may have available in every php scripts the same PDO Connection Objetc but you will end up to face issues with that way ... but it is not reconmmanded as PHP Programming Best Pratices ... the best way to do so is to include a connection file for every script in your project. Read PHP Documentation for Persistant Connections in order to learn more about Issues found for these Connection Objets especially for recent php versions. PHP Announced that Persistant Connections are on the way to be dropped from futur version as it may increase server workload with persistant ressources ... Sorry if it is too late
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
How can you have only one declaration of the database connection variable, $dbconn?
My login script is based on the following procedure
If the user is not authenticated, he is thrown back to the login page
If the user is authenticated, he gets an $_SESSION["logged_in"] = true;
Then when the user is browsing the main page or other pages that need auth, they just check if the $_SESSION["auth"] is set.
I have the database variable only at the beginning of my index.php:
$dbconn = pg_connect("host=localhost port=5432 dbname=masi user=masi password=123");
I do not the connection by db_close() anywhere in my codes.
I source my login script to index.php which uses my database.
However, I get the standard warnings of not getting access to db when I do not have the variable declaration also in my scripts. If I add the declaration to each of my scripts, I get an access to db.
We need to first understand how PHP is running the show here before we can delve into the wide, wide world of database connections.
Each PHP page request fires off a new PHP script. While you may have sessions turned on, that's an internal PHP construct only. The database sees this as a new connection/process connecting to the server. Therefore, it creates a new process on the database for it, so long as you call your pg_connect code. Otherwise, Postgres has no idea who you are or what session you want to use. Moreover, once the parent process dies, it generally kills the Postgres session (in this case, the PHP script runs and then dies once it's finished). Sometimes these can leave zombies roaming the streets of Postgres, but by and large, it'll just kill them.
If you want to use SQL code in your PHP script, you must connect to the database in that script before making a call to Postgres.
If i remember your other question you're redirecting to login.php? Which means that no the dbconn variable will not exist because it was initialised on another page.
if you required login.php from index.php it would work
$dbconn = pg_connect("host=localhost port=5432 dbname=masi user=masi password=123");
require_once('login.php');