php mysql check if connection is already established - php

This question differs from checking if the specific connection is alive or not which I found in SO itself and in Google Search Resutls.
What I want is to check if the mysql connection has already been established. I need to check this, because I have many modules which needs connection to function. The same module is sometimes called where there is no connection and sometimes called when there is already an connection.

You should simply call mysql_connect with the same arguments. If an identical connection already exists, it will simply be reused.
That was the lazy answer. Obviously the better way would be to structure your program in a way that you know what your program's status is. Getting rid of the age-old, deprecated mysql_ extension is a first step. Use mysqli or PDO, both of which do not support implicit connections but require you to hand a variable around that represents your connection. That's what you should do anyway for a sane and modular application structure, then you would not have these kinds of questions.

I suggest use singleton pattern and some OO.
class Singleton{
private static $instance=null;
public function connection(){
if(self::$instance==null){
self::$instance = mysql_connect();
}
return self::$connection;
}
}
class TableA extends Singleton{
function find($id){
$query="select * from `A` where `id`='$id'";
mysql_query($query, $this->connection());
... // other codes
}
}
hope that will help you

Related

How to reuse a MySQLi connection

I've ran into an issue with user already has more than 'max_user_connections' active connections
This happens because I use functions for the website functionality, each function contains a
$mysqli = connect();
Though at the same time, each function closes the mysqli at the end of function
mysqli_close($mysqli);
I do not want to include $mysqli as a parameter of the function, as the function is dynamic and would be tiresome to include it with each function call.
the connect() function just contains:
$mysqli = new mysqli(...);
return $mysqli;
I believe the error is thrown because the function sometimes calls itself for different executions, based on user input and pre-requisites... even though the mysqli is closed at the end of the function...
I'd like to know if there is a way of re-using a $mysqli connection sort of like in a global way...
I'm not sure whether I've explained myself fully so if you need some more information please leave a comment.
The proper way to reuse the same object across multiple functions/classes is to use dependency injection. Together with DI container, it can take care of providing the necessary dependencies to your functions leaving them clean.
The principle of clean code demands that your functions do not have side effects and they only do what their name states. This means that you should never be using globals in your functions as that would be causing side effects. The proper way to provide data without side effects to your function is via parameters. A connection to the database is the data that is required by your function.
If your code will be used as some kind of public library, it's even more reason to keep it clean. A function cannot have surprising behaviour. The best way to reduce surprises is by having a clear function signature. This means that all dependencies are listed as parameters with their correct types, the function cannot take dynamic arguments, and the return type must be clearly specified.
When it comes to mysqli connections (or PDO for that matter which you should prefer over mysqli), the connection should only be opened once during the execution of the script. You should never need to close the connection manually.
Here's an example of clean code. Let's imagine that you need to save bookings in the database. You create a service in your model:
<?php
class BookingService
{
public function __construct(protected mysqli $mysqli)
{
}
public function saveBooking(Booking $booking)
{
$stmt = $this->mysqli->prepare('INSERT INTO bookings (date, surname) VALUES (?,?)');
$stmt->execute([$booking->getDate(), $booking->getSurname()]);
}
}
Then in your controller, you just use your service as a dependency:
class BookingController
{
public function __construct(protected BookingService $bookingService)
{
}
public function index(Request $request)
{
$boooking = new Booking($request->get('date'), $request->get('surname'));
$this->bookingService->saveBooking($boooking);
}
}
Your DI container takes care of instantiating the mysqli and BookingService class. You can only create value objects in your controller. The necessary data is passed via parameters. This makes for a very clean and understandable code. Everyone knows what each function does, there are no surprises and everything has type specified.
There are a number of techniques to instantiate a variable only once. This is an anti-solution. Please do not use solutions listed here!
Static variable
If you only want a variable to be instantiated the first time the function is called, you can use a static variable.
function foo(){
static $mysqli;
if ($mysqli === null) {
$mysqli = connect();
}
// call the same function in recursive mode and the same connection will be reused
foo();
// do not close the connection manually!
}
This is a bad solution because your function fetches the dependency manually. You should not create functions that have side effects or multiple objectives. A function that connects should not be called from within a function that does something else. This leads to nightmarish code, which is the reason why you are having this problem now.
Using singleton
Singletons are bad for testing and for code readability. Anytime you need to change the dependency, you need to change all the places where the singleton is used. For a better explanation of why they are bad see What are drawbacks or disadvantages of singleton pattern?
Using globals
Globals are very bad for code maintainability. They are the bane of programmers since forever. It's precisely the reason why we have encapsulation and dependency injection.
Using a global would be very similar to using a static variable, except that the side effect is now global.
function foo(){
// declare a variable as global.
// this will instantiate the variable to null if it doesn't exist as a global yet
global $mysqli;
// if it's null, connect
if ($mysqli === null) {
$mysqli = connect();
}
// call the same function in recursive mode and the same connection will be reused
foo();
// do not close the connection manually!
// but if you must close the connection, just set the variable back to null
}
Do not use any of the above solutions! These are examples of bad unmaintainable spaghetti code. A programmer's nightmare. This answer is only supposed to be a warning of what not to do!

Static Varible vs PDO::ATTR_PERSISTENT

I have a database class that I developed. But I have doubts about performance in case of load. There are two issues that I was curious about and couldn't find the answer even though I searched.
When the database connection is bound to a static variable in the class,
class DB
{
static $connect;
......
function __construct()
{
try {
self::$connect = new PDO("{$this->db_database}:host={$this->db_host};dbname={$this->db_name};charset=utf8mb4", "{$this->db_username}", "{$this->db_password}");
self::$connect->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
self::$connect->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAMES utf8mb4");
} catch ( PDOException $e ){
echo '<b>ERROR: </b>'.$e->getMessage();
exit;
}
}
}
PDO::ATTR_PERSISTENT => true
Does it have an equivalent ability?
Also, I didn't fully understand the pdo permalink logic, it uses the existing connection instead of opening a separate connection for each user. But how does he use the existing link here? For example "ip address" etc.
Thank you for your help.
Let me approach the issues from a different direction.
A program should have only one connection to the database. (There are rare exceptions.) Your code, as it stands, seems to be inconsistent. It has a single ("static") connection, yet the class can be instantiated multiple times, thereby connecting multiple times. (I don't want to depend on anything "persist" to clean up the inconsistency.)
Either make the class a singleton or otherwise avoid being able to call __construct a second time. One approach goes something like this:
class DB {
private static $connect;
......
public function __construct() {
if (! self::$connect) {
self::$connect = ...
}
}
public function Fetch(...) {
self::$connect->...
return ...;
}
$con = new DB();
$data = $con->Fetch(...);
(plus suitable try/catch)
Note that that allows you to sub-class as needed.
Another approach might involve preventing the use of new:
private function __construct() { ... }
plus having some public method invoke that constructor.
Here's another approach. It can be used on an existing class that you don't want to (or can't) modify:
function GetConnection() {
static $db;
if (! $db) {
$db = new ...;
}
return $db;
}
$db = GetConnection();
$db->Fetch(...)'
As for "connection pooling", it is of limited use with MySQL. (Other products need it much more than MySQL does.) In my opinion, don't worry about such.
Do not use "auto-reconnect". If the connection dies in the middle of a transaction and is automatically restarted, then the first part of the transaction will be rolled back while the rest might get committed. That is likely to lead to data inconsistency.
Singletons, statics, globals, void*, critical sections all make me cringe. When I need such, I rush to find a way to "hide" it, even if that means writing cryptic code in some class(es).
For performance, MySQL really needs a single connection throughout the program. I compromise by hiding the connection in a "static" that serves at a "global". Then I hide that inside the class that I use to abstract the object(s).
I agree with Karwin's [now delete] Answer -- that this discussion is "much ado about nothing". MySQL performance is mostly about indexing, query formulation, and even the architecture of the application. Not about connections, common code elimination, redundant function calls, etc.

Bad practise to open and close mysql in every function

Example:
class SimpleClass{
public function foo() {
mysql_open();
//do mysql query here
mysql_close();
}
public function boo() {
mysql_open();
//do mysql query here
mysql_close();
}
}
Or is it better to have one mysql_open in the beginning of the class and one in the end?
Thanks.
EDIT: I use mysqli, this is just an example.
Should I open and close in each page file instead? Like in index.php, cataegory.php should have one open and close each.
Yes, It is bad practice. Here are reasons:
cost of making connectio is high
cannot use transaction during many function is called
every instance has it's own connection. It's too bad
and so on
Use PDO, or make singleton db class youself.
I would recommend wrapping the connection inside of a DAO class that operates as a singleton to manage your connection. In addition to what others have said above regarding prepared statements, and deprecated functions, I'm going to use those same deprecated functions to demonstrate the DAO concept
<?php
class MyGreatDAO{
private static $con = null//late static feature in php 5.3
private __construct(){
}
public static getInstance(){
if($con === null){
$con = mysql_connect($server,$user,$pass);
}
return $con;
}//untested
Basically, the idea is to prevent unnecessary data connections for performance reasons, and just persist the same connection throughout execution. You can use this same class to perform other DB operations as well on $con

Check if a specific mysql connection already exists during a php script?

I have a class for each database table object. Each class takes care of connection/queries/data format (database table specific logic) as I prefer to assign a connection for each class for better modularity. Also, I am using specific connections for some tables and queries.
My question is how can I check if a connection already exists so it won't start another one?
Basically I want to check if the connection with the same username/password/database has already been made. Or is this not necessary because mySql won't start a new connection for the same user? If that is so then please explain.
After further research found out that this is not possible ... it would require to get the thread id and use the conn with the thread id and it would act like a persistant conn; Or it would require to keep track every thread ids used during a script and it's kinda useless.
There isn't yet a spimple method of doing this ... persistant connection can be a choice but then u have to take care of connection clean up and again sux :)
P.S. : Eventually i did made a tracking system for the connections during my app run (the guys that said to store them in a globally available object we're right). Stored conn object and conn params in 2 arrays in a singleton class object, checked if the params allready exists in params array , if not make new conn , if yes get the conn object from the array-key thats the same with the key where params were found... I allready had the arhitecture made for this but didnt want to use that class...not the logic i began with :), and also wanted to make it in a library item, thats why i was looking for a simple and abstract solution but there is only a particular solution :)
Create new connection for each class is not a good idea. It may be modularized to you but your mysql server will be soon bloated with too may connections error.
I suggest use singleton pattern and some OO.
class Singleton{
private static $instance=null;
public function connection(){
if(self::$instance==null){
self::$instance = mysql_connect(); // define it in your way,
}
return self::$connection;
}
}
class TableA extends Singleton{
function find($id){
$query="select * from `A` where `id`='$id'";
mysql_query($query, $this->connection());
... // other codes
}
}
I suggest you read this - I think this will help you http://www.php.net/manual/en/features.persistent-connections.php
If you must have a different connection for each class, you can use a static class property to hold the connection, and use the singleton pattern to retrieve it.
class SomeTable {
// Connection resource as a static property
// Since it is static, it will be shared by all instances of class SomeTable
public static $db = FALSE;
// Static method to retrieve the connection
// or create it if it doesn't exist
public static function get_conn() {
if (self::$db) {
// Just return the connection if it already exists
return self::$db;
}
else {
// If it doesn't already exist, create it and return it
self::$db = mysql_connect(...);
return self::$db;
}
}
// In other methods, use self::get_conn()
public function someQuery() {
$sql = "SELECT col FROM tbl";
// Call the connection singleton explicitly
// as the second param to mysql_query()
$result = mysql_query($sql, self::get_conn());
}
}

How do you efficiently connect to mysql in php without reconnecting on every query

I'm pretty sick of having to rewrite my code every time I learn something new about php (like the fact that mysql connections cannot be passed around in a session as a handle).
How do you implement mysql connection in your projects? A lot of people have proposed "connection pooling", but after reading the manual i'm still lost. It's like: "connection pooling is mysql_pconnect!" - me: "and...? how is that any different in reality? can you pass around a mysql_pconnect in a session? why is this seemingly mysterious aura??"
Let me explain my situation. I have a function called "query1":
function query1($query)
{
$db = new mysql(HOST,USER,PASS,DBNAME);
$result = $db->query($query);
$db->close();
return $result;
}
This is seems like a squanderous and inefficient way of querying a db (especially since you need a mysql handle for functions like mysql_real_escape_string). What is the correct form to do it? Can someone please help me?
Thank you I'd really appreciate a good honest answer.
Normally connections happen once a page load. AKA
class Database{
public function connect()
{
$this->connection = mysql_connect();
}
// This will be called at the end of the script.
public function __destruct()
{
mysql_close($this->connection);
}
public function query($query)
{
return mysql_query($query, $this->connection);
}
}
$database = new Database;
$database->connect();
$database->query("INSERT INTO TABLE (`Name`) VALUES('Chacha')");
Basically, you open the connection in the beginning of the page, close it at the end page. Then, you can make various queries during the page and don't have to do anything to the connection.
You could even do the mysql_connect in the constructor as Erik suggest.
To use the above using global variables (not suggested as it creates global state), you would do something like
Global $db;
$db = new Database;
// ... do startup stuff
function doSomething()
{
Global $db;
$db->query("Do Something");
}
Oh, and no one mentioned you don't have to pass around a parameter. Just connect
mysql_connect();
Then, mysql_query will just use the last connection no matter what the scope is.
mysql_connect();
function doSomething()
{
mysql_query("Do something");
}
Per the comments:
I think you should use mysql_pconnect() instead of mysql_connect(), because mysql_connect() doesn't use connection pooling. – nightcoder
You might want to consider whether you use mysql_connect or mysql_pconnect. However, you should still only connect once per script.
You don't need to connect to the database in every function. You need to connect to the database when the script starts running and save connection object in global state. In any function you can use that connection object to query the database. Your connection object will be recreated for every time script is executed but it will be very fast, because special connection pool is used behind the scene, so connection will be done immediately (matter of microseconds, because actually connection was not even broken, it was saved in connection pool).
Here is the example you asked for:
// this code should be executed on every page/script load:
$adoConn = ADONewConnection(...);
$adoConn->PConnect(...);
// ...
//And then in any place you can just write:
global $adoConn;
$adoConn->ExecuteNonQuery("INSERT INTO test SET Value = 'Hello, world!'");
As for your question "how do I implement connection pool". You don't. It's maintained by the server behind the scene and used if you (or the PHP library for work with PHP) use mysql_pconnect() function.
PS. If you are afraid to keep $adoConn as a global variable (I'm not) then you can create a class with a static property:
class DB
{
public static $adoConn;
}
// ...
DB::$adoConn->ExecuteNonQuery(...);

Categories