Below is my DB connection class. The problem is that when I try to access the CloseConnection function from my code, it gives error: "Unknown MySQL localhost". I use "dbconnection::CloseConnection" through my other code files. It is successfully opening the connection, but giving error in "$conn".
final class dbconnection
{
private $conn;
//Opens connection for a MySQL DB
public static function OpenConnection()
{
require("../Config/dbconfig.php");
$conn = mysql_connect(DB_HOST,DB_USER,DB_PASSWORD);
mysql_select_db('MyDB');
}
//Closes connection for a MySQL DB
public static function CloseConnection()
{
mysql_close($conn);
}
}
Below is a method in another PHP file from where I access the above functions:
public static function InsertRecord($inQuery)
{
dbconnection::OpenConnection();
$resultSet = mysql_query($inQuery);
dbconnection::CloseConnection();
return $resultSet;
}
When I remove the line "dbconnection::CloseConnection()", it works fine. I also want to know whether it is a good practice to immediately close the connection as the DB task is finished, or should I keep it open till the use closes the browser?
Try:
class dbconnection {
private static $conn;
public static function OpenConnection() {
require("../Config/dbconfig.php");
self::$conn = mysql_connect(DB_HOST,DB_USER,DB_PASSWORD);
mysql_select_db('MyDB');
}
public static function CloseConnection() {
mysql_close(self::$conn);
}
}
What you're doing is trying to access the member variable $conn but you're doing it incorrectly so you're simply creating a new (local) variable to use. That doesn't matter on open (the reference is simply discarded) but on close you're not dealing with a resource reference anymore.
Secondly, your functions are static but your member variable isn't. These are the two methods you use for accessing member variables:
class A {
private $a;
private static $b;
public static function foo() {
$this->a = 3; // instance member
self::$b = 4; // static member
}
}
Edit: regarding the last function, it works when you remove the call to CloseConnection() because it is no longer trying to access a database connection via the local variable $conn (which will cause an error).
No it isn't good practice to close a database connection immediately. The most common practice in PHP is simply to open a connection at the top of your script and then do nothing more. When the script exits it will close. Some people open connections on demand, meaning it won't try to create one until it needs one. This is an acceptable optimization (from the point of view of not adding unnecessary complexity). Generally the connection will never be explicitly closed. It will be closed implicitly when the script ends.
Long-lived scripts may want to take a different approach just so they don't unnecessarily hold open connections for extended periods.
You may at some point want to use persistent connections instead.
The above method is simple enough and sufficient enough for some pretty large sites. As a general rule, don't try to optimize this stuff and introduce unneeded complexity until you actually have a problem that you need to do something about.
Related
I know we always have to close db connection at the end. Let's I have a class and there is four methods and each consists of db queries. Now my question is
Should I create a connection and close it in every different methods
or create the connection in the constructor of the class? If I create
the connection in the constructor then where will I close it. Because
If I close that in any function no other method can access it.
If I create new connection for every method then no of connections may be very high. Then where will I create and close the function proper way?
If you open it, then you need to close it.
As long as you close the connection, you can close it where you want. It seems like maybe your closing woes are more about the design of the procedures of your program. Just because the database call uses a connection doesn't mean it has to be opened and closed right there with it.
Say you might want to reuse a $mysqli variable that's holding a connection. You can pass that connection to a function and either return it or close it inside. In this way, you can isolate the main activity of the database call in the body of the function without having to worry too much about the opening and closing of everything.
Using that technique, it's possible to reuse a connection for multiple queries, contained each inside their own method. Maybe you would be better off opening a class and passing a $mysqli connection to it, as needed.
This depends on your program and your choices about how it will work.
If you are developing a program, and you're curious about the impact of your opening and closing actions, you can call http://php.net/manual/en/mysqli.stat.php or a similar function. If you are opening many threads and not closing them, then you would see the thread count escalate in the answer from mysqli_stat().
The calls may not close, for example, if you have a poorly designed query that runs away from you; the scope of the connection object should close naturally with the end of the script.
Because of the reference-counting system of php it's not necessary to close the connection, it will be freed automatically (unless you open persistent db links), so it shouldn't cause a headache.
You should open the connection only once btw.
Please take into consider transaction concept. Say for example you methods are being called in a sequence, it makes sense to open a connection and keep it open
If there is delay in call of other methods, i would not advice you to keep connection suspended especially if multiple people are going to access the application
Best way would be to implement classes and extend it to your functional class containing methods. Constructor of the extended class can call to the connection function and the destructor can call to disconnect whenever the object is set to NULL.
Or
As your question states, have two functions in base class having construction and other having destruction.
Call to the constructor function before using your connection and destroy it after using.
Example would be:
class bar{
protected function connect(){
#connect to db
}
protected function disconnect(){
#disconnect db
}
class foo extends bar{
function func1 () {
$this->connect();
#Code
$this->disconnect();
}
function func2() {
$this->connect();
#Code
$this->disconnect();
}
function func3() {
$this->connect();
#Code
$this->disconnect();
}
function func4() {
$this->connect();
#Code
$this->disconnect();
}
?>
I have the following database class. My thinking was that this will check for an existing instance of the class and return that rather than create a new database connection.
When I run the code it creates a connection. When I refresh the page another connection is created (checked MySQL connections).
Is my thinking incorrect? Fairly new to using OOP so apologies for the newbie question!
Any help or pointers in the right direction would be appreciated.
Many thanks.
<?php
class Db
{
private $_connection;
private static $_instance;
private $_host = 'localhost';
private $_username = 'root';
private $_password = 'password';
private $_database = 'test';
public static function getInstance()
{
if (!self::$_instance) {
self::$_instance = new self();
}
return self::$_instance;
}
private function __construct()
{
try {
$this->_connection = new PDO("mysql:host=$this->_host;dbname=$this->_database", $this->_username, $this->_password);
echo 'Connected to database';
} catch (PDOException $e) {
echo $e->getMessage();
}
}
private function __clone()
{
}
public function getConnection()
{
return $this->_connection;
}
}
$db = Db::getInstance();
PHP is a "shared nothing" environment. Each request handled by a PHP application is isolated from all other requests either as a separate thread or a separate process depending on the server api (SAPI) being used. The class you have designed is a singleton but it is isolated to a single request-response cycle. This means that if you call Db::getInstance() 10 times during a single request you will get 10 references to the same object, but a single call in a separate request will create and return a distinct object.
You can use some type of connection pooling, either on the server or application side, to reduce the number of concurrent connections made to your backend database server. PHP's PDO abstraction enables application side connection pooling via the PDO::ATTR_PERSISTENT connection driver option. These pooled connections are cached in the PHP parent process rather than the worker thread/process that handles a request and subsequently reused. The exact number of connections that will be opened and how they are shared is variable depending on your SAPI and underlying database type.
When utilizing PHP for your server side language, understanding what happens in the background is probably a good thing.
PHP initiates the connection for you when you run that code. It does not persist the connection past the page load.
On each page load new connections will be opened so you can continue to make your requests and perform your tasks.
Consider what would happen if it did. You close the page and go to sleep and the server sits with an open connection to the database forever. You get a few visitors and then you hit your connection limit and get a too many connections error.
There are probably some references to cite, but I really can't find many as this is more of a logical problem then a coding problem.
Each time you refresh your page, you are instantiating a brand new Db object, and assigning it to a brand new variable called $db, so you get connections each time. I also think you may be overcomplicating your Db class.
When I reate db class to wrap PDO or mysqli, the idea is to create a db object, that when instantiated would include a database connection as one of it's attributes. To accomplish that, I'd rewrite your class a bit. Something like this would be all you need to create Db object with a private connection that can be used by any range of other methods you wish to add to the class... Say, a method to issue a query,
class Db
{
private $_connection;
private $_host = 'localhost';
private $_username = 'root';
private $_password = 'flindersbeast';
private $_database = 'flinders';
public function __construct()
{
try {
$this->_connection = new PDO("mysql:host=$this->_host;dbname=$this->_database", $this->_username, $this->_password);
echo 'Connected to database';
} catch (PDOException $e) {
echo $e->getMessage();
}
}
// Other methods here will use $this->_connection to do a variety of things.
public function example()
{
// Do stuff - as needed you can pass $this->_connection to PDO
}
}
$db = new Db;
Good luck!
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
I am making my first steps in the OOP world - please bear with me.
I know that having many ongoing mySQL connections open at the same time can be fatal for performance, so it should be a good idea to make a database class that takes this into account.
Is $this->session->write(...); going to result in a new mySQL connection being opened each time?
Or is that up to the "persistent connection" feature in mySQL?
Here's the code:
abstract class database {
function __construct() {
//mysql_connect()
}
}
class session extends database {
function write () {
// mysql_query(--.)
}
}
Is session handler some kind of specialized type of database? It is not, so don't use inheritance (a is a relationship). Session handler uses database so you should use composition (a has a relationship):
class Session {
protected $db;
public function __construct(DB $db) {
$this->db = $db;
}
public function write() {
$this->db->query(...);
}
}
$db = new DB(...);
$session = new Session($db);
Also, don't use mysql_*() functions. Use much more powerful PDO.
Returning to your question... mysql_connect() will be executed every time you create a new Database object. However in this case Session is an object of type Database so every time you write new Database() or new Session() the constructor is invoked, therefore mysql_connect() is invoked as well.
PS. mysql_connect() function won't create a new connection if specified connection already exists. Check 4th argument of this function to learn more.
mysql_query will create a new connection only if no previous mysql connection has been made. Otherwise, it will either use the connection you specify or the last connection opened with mysql_connect. http://php.net/manual/en/function.mysql-query.php
Why not
class database {
function __construct() {
//mysql_connect()
}
function write() {
//query the DB
}
}
I'm not sure of the syntax, I don't do OOP PHP. Anyway, in your structure above a new connection would be opened for each "session" instance so assuming you only create one instance of "session" you won't be openeing loads of database connections.
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(...);