I have a webpage with some mysql querys,
I must start new db connection and db close after every query or its more efficiently start an only one db connection at the top of the code and close at the bottom of the script?
Thanks!
Never create a new connection for every query; it's very wasteful and will overburden your MySQL server.
Creating one connection at the top of your script is enough - all subsequent queries will use that connection until the end of the page. You can even use that connection in other scripts that are include()ed into the script with your mysql_connect() call in it.
I prefer to create some sort of class called Database of which upon creation will create a database connection using mysqli (OOP version of mysql).
This way i do not have to worry about that and i have a static class that has access to the database.
class MyAPI {
private static $database = false;
public static function GetDatabase() {
if (MyAPI::$database === false) {
MyAPI::$database = new Database(credentials can go here)
}
return MyAPI::$database;
}
}
Now your system with the includsion of your API and your database can access the database and its initialization code does not have to be peppered around your files depending on what part of the program is running and your database/connection will not be created if it is not needed (only until it is called).
Just for fun i also like to have a function in my Database class that will perform a query and return its results, this way i do not have to have the SAME while loop over and over again throughout my code depending on where i make these calls.
I also forgot to answer your question. No multiple connections! its baaaad.
Only create one connection. You don't even have to close it manually.
multiple connexion is better for security and tracking.
if you're going though a firewall between front and back there will be a timeout defined so a single connection will be a problem.
but if your web server is on the same host as mysql, a single connection will be more efficient.
Related
i'm using Slim framework to provide an API to our clients. I'm focused on Java so that could the the point, because the problem is related with database connection.
Every request connect to the database throw PDO like
$dbh = new PDO($param1, $param2, $param3);//php 7.1
So as php don't have a connection pool i understand each request (maybe at the same time) starts a new connection throw the database.
But i'm experimenting a kind of situation here.
If one request starts a transaction for inserting or updating something, next requests will wait until this transaction finish, but it is on a different thread, so i'm thinking on table locks? or something like each request is getting the same connection.
THE PROBLEM:
So if they are in different threads with a different connection how
they need to wait until transaction ends for the first request.
My database source class is something like
class DataBaseConfig {
public static function getConn()
{
$dbh = new PDO($param1, $param2, $param3);
$dbh->exec("set names utf8");
return $dbh;
}
}
And i use it like
$db = DataBaseConfig::getConn();
$db->beginTransaction();
//code
$db->commit();
I'm missing something sure, so can someone help me with this problem?
Thanks!
NEWS! EDIT
#YourCommonSense thank you it was finally a session configuration. I
didn't know that php start_session(); locks the session file so that's
what was happening. Thanks a lot!
link: https://ma.ttias.be/php-session-locking-prevent-sessions-blocking-in-requests/
I am doing project using mongodb and zendframework 2 so here I create connection in the constructor
private $conn;
public function __construct(){
$this->conn = new \MongoClient('mongodb://example.com:27017', array("connect" => TRUE));
}
It contain several actions to perform database operations like createdb, dropdb, renamedb like wise. so I close that connection within the __distruct() method
public function __destruct(){
$this->conn->close();
}
my code works fine. but I would like to know is this ok?
PHP closes database connections automatically.
You can read more about this in this post
however
read this
quote:
"Open connections (and similar resources) are automatically destroyed at the end of script execution. However, you should still close or free all connections, result sets and statement handles as soon as they are no longer required. This will help return resources to PHP and MySQL faster."
So basically, in case you have tons of things going in and out of the database, then yes, you might want to close right after.
In my opinion it is rather optional and your own choice wether to kill the process or not.
I am using Zend Framework for my PHP developments and here is a small function I used to execute a query. This is not about an error. The code and everything works fine. But I want to know some concept behind this.
/**
* Get dataset by executing sql statement
*
* #param string $sql - SQL Statement to be executed
*
* #return bool
*/
public function executeQuery($sql)
{
$this->sqlStatement = $sql;
if ($this->isDebug)
{
echo $sql;
exit;
}
$objSQL = $this->objDB->getAdapter()->prepare($sql);
try
{
return $objSQL->execute();
}
catch(Exception $error)
{
$this->logMessage($error->getMessage() . " SQL : " .$sql);
return false;
}
return false;
}
Bellow are unclear areas for me.
How Zend_Db_Table_Abstract Maintain database connections?
Is it creating new connection all the time when I call this function or Does it have some connection pooling?
I didn't write any coding to open or close database connection. So will zend framework automatically close connections?
If this open and close connection works all the time if I execute this function, Is there any performance issue?
Thank you and appreciate your suggestions and opinion on this.
Creating Connection
Creating an instance of an Adapter class does not immediately connect to the RDBMS server. The Adapter saves the connection parameters, and makes the actual connection on demand, the first time you need to execute a query. This ensures that creating an Adapter object is quick and inexpensive. You can create an instance of an Adapter even if you are not certain that you need to run any database queries during the current request your application is serving.
If you need to force the Adapter to connect to the RDBMS, use the getConnection() method. This method returns an object for the connection as represented by the respective PHP database extension. For example, if you use any of the Adapter classes for PDO drivers, then getConnection() returns the PDO object, after initiating it as a live connection to the specific database.
It can be useful to force the connection if you want to catch any exceptions it throws as a result of invalid account credentials, or other failure to connect to the RDBMS server. These exceptions are not thrown until the connection is made, so it can help simplify your application code if you handle the exceptions in one place, instead of at the time of the first query against the database.
Additionally, an adapter can get serialized to store it, for example, in a session variable. This can be very useful not only for the adapter itself, but for other objects that aggregate it, like a Zend_Db_Select object. By default, adapters are allowed to be serialized, if you don't want it, you should consider passing the Zend_Db::ALLOW_SERIALIZATION option with FALSE, see the example above. To respect lazy connections principle, the adapter won't reconnect itself after being unserialized. You must then call getConnection() yourself. You can make the adapter auto-reconnect by passing the Zend_Db::AUTO_RECONNECT_ON_UNSERIALIZE with TRUE as an adapter option.
Closing a Connection
Normally it is not necessary to close a database connection. PHP automatically cleans up all resources and the end of a request. Database extensions are designed to close the connection as the reference to the resource object is cleaned up.
However, if you have a long-duration PHP script that initiates many database connections, you might need to close the connection, to avoid exhausting the capacity of your RDBMS server. You can use the Adapter's closeConnection() method to explicitly close the underlying database connection.
Since release 1.7.2, you could check you are currently connected to the RDBMS server with the method isConnected(). This means that a connection resource has been initiated and wasn't closed. This function is not currently able to test for example a server side closing of the connection. This is internally use to close the connection. It allow you to close the connection multiple times without errors. It was already the case before 1.7.2 for PDO adapters but not for the others.
More information
My question is I am using the variable $db in my general script code and within one of my functions. It's purpose is to be the variable that is used for MySQL connections. I have a need inside a function to write some data to the database. In my script I cannot assume that an existing db connection will be open so I open a new one and close it before the function exits. Ever since doing this I am getting an error after the script runs saying the MySQL reference is bad / doesn't exist.
The only thing I can pin it to is in my core code I use the variable $db as the variable name for database connection. I also use the same variable in the function. I did not imagine this would be a problem because I do not use global in front of $db in the function. This should mean the $db I reference in my function is in the functions private scope but it seems to be closing the public $db's connection.
Any thoughts?
Fragments of my code are:
database.php
db_connect()
{
// open mysql db connection and return it;
}
db_close( &$db )
{
// close the passed by reference db connection
}
api.php
api_verify( $keyid, $userid, $key )
{
// open a new db connection
$db = db_connect();
// check for errors. if any errors are found note them in the db
// close the db
db_close($db);
}
main.php
include api.php;
include database.php;
// open a connection to the db
$db = db_connect();
// pull a list of things to process from the db and move through them one at a time
// call api_verify() on each key before working through it's data.
db_close($db)
To manage DB connections, you can create a class rather than a pair of functions. If where you say "MySQL reference", the exact error refers to a "MySQL resource", then you are using the outdated mysql extension and should switch to a more modern extension, such as PDO.
class DBConnection {
protected static $_connections = array(),
static connect($dsn) {
if (!isset(self::$_connections[$dsn])) {
$credentials = self::getCredentials();
/* Create connection. For example: */
try {
self::$_connections[$dsn][0] = new PDO($dsn, $credentials['username'], $credentials['password']);
} catch (PDOException $exc) {
// erase the frame w/ password from call trace to prevent leak.
throw new PDOException($exc->getMessage(), $exc->getCode());
}
/* End create connection example */
self::$_connections[$dsn][0]->dsn = $dsn;
}
++self::$_connections[$dsn]['count'];
return self::$_connections[$dsn][0];
}
static close($db) {
if (isset(self::$_connections[$db->dsn])) {
if (--(self::$_connections[$db->dsn]['count']) < 1) {
unset(self::$_connections[$db->dsn]);
}
}
}
static getCredentials() {
/* credentials can be stored in configuration file or script, in this method, or some other approach of your own devising */
}
}
Note that this isn't exactly OOP (it is, but only in a technical sense). The above doesn't lend itself well to unit testing. If you want a more OO approach (which will be more amenable to unit testing), extend or wrap PDO. Using dependency injection can also help with the coupling issues of the above.
I assume you are opening a connection to the same database with the same username/password at each of the places you call db_connect. When doing so,unless your db_connect explicitly specifies, that you are creating a new link, it will return an already opened link.If that link is then closed using db_close(), it will also close the other connection, since the link is the same. If you are using mysql_connect to connect to the database, it takes an argument called new link
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.
Refer to http://php.net/manual/en/function.mysql-connect.php
I'm not sure if this is the issue you are facing. Hope it helps.
I would assume what is happening is the connect cancels out because there already is a connection, and then the close ends the current connection.
I would recommend either A) start a connection at the beginning of the file, and just know it's always there (what I do); or B) check the to see if the $db variable is set, if not then create the connection, and always end the connection at the end of the file.
HI everyone, I was just wondering what the best way to make multiple queries against tables in a mysql databases is. Should I be making a new mysqli object for every different .php page ($mysqli = new mysqli("localhost", "root", "root", "db");)?
Or is there a way to reuse this one time over all php files in my website? Any suggestions would be pretty cool
My vote would be to take an OOP approach. I would have one script that has a DB conn class in it and a method in that class to check if a connection exists and if it does returns the connection object. You could have that db class script referenced [ include_once(); ] on the pages that need to access the database. Then it would be a matter of instantiating the db object, firing the "if-exists" method and if it returns true then just utilize the existing connection within the object.
You could also take a look at utilizing persitent connections to the DB
Persistent connections
However honestly you will be better off in the long run and scalability of your application to handle the db connection management yourself rather then leaving a connection constantly open.
Here is an example of how I would structure that class:
As a note, made by #alex, the mysql_error() should not be echoed to the page in an environment where the display_errors() is set to display all warnings. (e.g error_reporting(E_WARNING);)
class dbconn {
protected $database;
function __construct(){
$this->connect();
}
protected function connect() {
$this->database = mysql_connect('host', 'user', 'pass') or die("<p>Error connecting to the database<br /><strong>" . mysql_error() ."</strong></p>" );
mysql_select_db('databasename') or die("<p>Error selecting the database<br />" . mysql_error() . "</strong></p>");
}
function __destruct(){
mysql_close($this->database);
}
function db(){
if (!isset($this->database)) {
$this->connect();
}
return $this->database;
}
}
You need to create the connection for each page, as each PHP script's lifetime is that of the request.
However, you can place the connection code in one file and then include it from all pages.
You could create a connect.php that validates it's being included by your application, and then creates a DB connection.
You could then include that file at the beginning of your application's init, or the beginning of any independent script that needs a connection =)
Depends on structure of website. If you have:
<a herf='login.php'>login</a>
<a herf='register.php'>register</a>
<a herf='about.php'>about</a>
..., then you'll have to connect in every PHP file, i.e., in login.php, in register.php and in about.php. To make it easier, I would either create config.php file which holds user/pass, or even do like Shad said.
You might also have index.php that contains something like this:
if ( !isset($_GET['module']) ) {
$_GET['module'] = 'about';
}
switch ( $_GET['module'] ) {
default:
case 'about':
include 'about.php';
break;
case 'login':
include 'login.php';
break;
case 'register':
include 'register.php';
break;
}
And HTML code:
<a herf='?module=login'>login</a>
<a herf='?module=register'>register</a>
<a herf='?module=about'>about</a>
In this case you can connect in index.php and then pass the connection to all other involved files.
The 2nd way seems to be more common to me, i.e., it feels more intuitive, more handy and that's what I always do.
I believe that in some cases it might be worthy (performance-wise) to use persistent connections and reserve/release connection when needed (either for transaction or even for single query). For example, simple system that I'm now working with takes 70ms-100ms to generate, and it takes only 40ms-50ms to do SQL queries. If using "single connection" approach, it means that connection is wasted for about 50% of time, while "reserve/release connection when needed" with persistent connections would not have such issue.
One more thing - I would advise you to create some wrapper, i.e., some DBConnection class that connects to DB in constructor and has methods like select() (returns array of data), selectValue() (returns single value, e.g., $db->selectValue('select count(*) from user') would return (int)$numberOfUsers), some exec() for inserts and updates etc.