I have a singleton database connection class- db.php (found by googling):
<?php
/*
* Mysql database class - only one connection alowed
*/
class db {
private $_connection;
private static $_instance; //The single instance
private $_host = "localhost";
private $_username = "user_name";
private $_password = "password";
private $_database = "database";
/*
Get an instance of the Database
#return Instance
*/
public static function getInstance() {
if(!self::$_instance) { // If no instance then make one
self::$_instance = new self();
}
return self::$_instance;
}
// Constructor
private function __construct() {
$this->_connection = new mysqli($this->_host, $this->_username,
$this->_password, $this->_database);
// Error handling
if(mysqli_connect_error()) {
trigger_error("Failed to conencto to MySQL: " . mysql_connect_error(),
E_USER_ERROR);
}
// Magic method clone is empty to prevent duplication of connection
private function __clone() { }
// Get mysqli connection
public function getConnection() {
return $this->_connection;
}
public function closeConnection(){
$this->_connection->close();
}
}
?>
To test the connectivity, If I extend that database class in ext.php like this:
<?php
class ext extends db {
private $conn;
function __construct(){
$this->connect();
if(isset($this->conn)){
echo 'Connection is established<br />';
}
$this->closeConn();
}
public function connect(){
$this->conn = parent::getInstance()->getConnection();
}
public function closeConn(){
parent::closeConnection();
}
}
?>
and in my index.php page:
<?php
spl_autoload_register(function ($class) {
include '../classes/' . $class . '.php';
});
$test = new ext();
?>
now my output is as below:
Connection is established
Fatal error: Call to a member function close() on a non-object in (line number) of db.php
my question is how can I close connection in extended class (ext.php)?
The solution would be like this:
First, create a private instance variable of parent class db in ext class, like this:
class ext extends db {
...
private $parentInstance;
...
}
Then use this instance variable $parentInstance to create and close your connection, like this:
class ext extends db {
private $conn;
private $parentInstance;
function __construct(){
$this->connect();
if(isset($this->conn)){
echo 'Connection is established<br />';
}
$this->closeConn();
}
public function connect(){
$this->parentInstance = parent::getInstance();
$this->conn = $this->parentInstance->getConnection();
}
public function closeConn(){
$this->parentInstance->closeConnection();
}
}
Sidenote: There's one small syntax error in db class as well. The closing parentheses of constructor method is missing.
Related
I am pretty new to PHP and try to learn it the OOP way as I have an understanding of it. My problem is I have no idea why I am getting the null error below when I try to get the mysqli connection.
Fatal error: Uncaught Error: Call to a member function getConn() on
null
<?php
class ConnectDB
{
private $conn;
private function __construct()
{
$this->conn = new mysqli('localhost', 'root', 'root', 'gs');
$this->checkConnection();
}
public function getConn()
{
return $this->conn;
}
/**
* #return ConnectDB
*/
public static function getInstance()
{
static $instance = null;
if($instance == null)
{
$instance == new ConnectDB();
}
return $instance;
}
public function checkConnection()
{
if($this->conn->connect_errno)
{
echo "Can't connect to Database: " .mysqli_connect_error();
exit();
}
else
{
echo "Connected!";
}
}
}
$conn = ConnectDB::getInstance()->getConn();
In your getInstance method, where you create the class instance you wrote $instance == new ConnectDB();. Use a single = for assignments.
I don't think that your getInstance method is a singleton at all. You are initializing the variable $instance in every call to null, so you should get a new instance every time.
Try it like this:
class ConnectDB
{
private $conn;
private static $instance = null;
...
public static function getInstance()
{
if(self::$instance == null)
{
self::$instance == new ConnectDB();
}
return self::$instance;
}
...
See if you can make this work:
<?php
class ConnectDB {
private $_connection;
private static $_instance; //The single instance
private $_host = "localhost";
private $_username = "root";
private $_password = "root";
private $_database = "gs";
//
public static function getInstance() {
if(!self::$_instance) { // If no instance then make one
self::$_instance = new self();
}
return self::$_instance;
}
// Constructor
private function __construct() {
$this->_connection = new mysqli($this->_host, $this->_username, $this->_password, $this->_database);
// Error handling
if(mysqli_connect_error()) {
trigger_error(
"Failed to conencto to MySQL: " . mysql_connect_error(),E_USER_ERROR
);
} else{
echo "Connected!";
}
}
private function __clone() { }
public function getConn() {
return $this->_connection;
}
$db = ConnectDB::getInstance();
$mysqli = $db->getConn();
}
?>
Below is the code for database connection. & there are more methods under it.
To keep it simple i decided to make a separate class for other methods.So is there anyway i can connect to database when instantiating other class.
Db.php
class Db{
private static $_instance = null;
private $_db;
private function __construct(){
try{
$this->_db = new PDO('mysql:host = localhost;dbname=db_xoo', 'root', '');
}
catch(PDOException $e){
die($e->getMessage());
}
}
public static function get_instance(){
if(!isset(self::$_instance)){
return self::$_instance = new Db();
}
else{
return self::$_instance;
}
}
Other.php
<?php
class Other{
.
.
.
public function blah(){
database queries..
}
.
.
}
?>
Now when i instantiate class other.What should i add in other.php so that it can make automatic connection to database instead of calling Db::get_instance() everytime before creating $test = new Other()
use constract in other class
like this
class Other{
private $_db;
private function __construct(){
$this->_db = Db::get_instance();
}
public function blah(){
database queries.. $this->_db->query()
}
.
.
}
I have a configuration file where I am defining my database configuration.
My configuration file is
<?php
$config['database']="mydb";
$config['host']="localhost";
$config['username']="root";
$config['password']="";
?>
I have a config class where I am assigning my configuration settings my config class is like
class Config {
//put your code here
protected $host = "";
protected $user = "";
protected $password = "";
protected $database = "";
protected function __construct(){
include_once 'configuration.php';
$this->host=$config['host'];
$this->user=$config['username'];
$this->password=$config['password'];
$this->database=$config['database'];
}
}
now I am trying to establish my database connection to my connection class like
include_once 'Config.php';
class Connection extends Config{
private $conn;
function __construct() {
parent::__construct();
try {
$this->conn = new PDO("mysql:host=$this->host;dbname=$this->database", $this->user, $this->password);
} catch (PDOException $pe) {
echo "Error connecting to database. " . $pe->getMessage();
}
}
function getConnectionObject() {
return $this->conn;
}
public function destroyConn() {
$this->conn = null;
}
}
My problem is when I am trying to get this connection for further class it showing me blank object
My code for access database connection object is
class Functions extends Connection {
private $conOb;
function __construct() {
parent::__construct();
$this->conOb = parent::getConnectionObject();
}
function getConnectionObject() {
parent::getConnectionObject();
}
}
if I am defining my database configuration in my connection class I am able to Access my connection object in my Function class but if I am trying to set it by configuration file getting Null connection object.
Please let me know where I am making mistake. Thanks in advance .
You're missing the return keyword
class Functions extends Connection {
private $conOb;
function __construct() {
parent::__construct();
$this->conOb = parent::getConnectionObject();
}
function getConnectionObject() {
return parent::getConnectionObject();
}
}
By the way, you don't have to redeclare the method getConnectionObject() if you don't add anything to it.
You can simply do :
class Functions extends Connection {
function __construct() {
parent::__construct();
}
}
$db = new Functions();
$dbh = $db->getConnectionObject();
And if you change the visibility of the property $conn to protected in the class Connection, you can use your connection in subclasses like that :
class Functions extends Connection {
function __construct() {
parent::__construct();
}
function doSomething() {
$this->conn->query('SELECT....');
}
}
As a side note, i encourage you to take a look at the PHP coding style standards.
here is my code
pdo.php
class Connection {
public function __construct() {
$this->connect ($db);
}
private function connect($db) {
try {
if (! $db){
$this->db = new PDO ( 'mysql:host=localhost;dbname=Shopping;charset=utf8', 'xxxx', 'xxxxx' );
echo 'Connected';
return $this->db;
}
catch ( PDOException $conError ) {
echo 'failed to connect DB' . $conError->getMessage ();
}
}
}
product.php
class ProductInsert extends Connection { //here my function is called multiple times
function __construct() {
parent::__construct($db);
}
public function prdInsert(.....)
{ ........}
here my problem is database connection is opened multiple time. when ever i am calling the productInsert() then database connection is opened how i can prevent this
Do not extend your application class from database class.
This is your main problem.
They are too different classes having nothing in common.
So you have to just use your db object as a property.
Connection class is also useless at the moment, as it's just a leaky disguise for the PDO.
So, just create raw PDO object and then pass it in the constructor of product
class ProductInsert
{
function __construct(PDO $db)
{
$this->db = $db;
}
public function prdInsert(.....)
}
And for goodness sake, learn to indent your code.
class Connection {
public function __construct($db) {
return $this->connect($db);
}
private function connect($db) {
try {
if (! $db){
$db = new PDO ( 'mysql:host=localhost;dbname=Shopping;charset=utf8', 'xxxx', 'xxxxx' );
echo 'new connection';
}
return $db;
}
catch ( PDOException $conError ) {
echo 'failed to connect DB' . $conError->getMessage ();
}
}
}
here is the solution
pdo.php
class Connection {
// Declare instance
private static $instance = NULL;
// the constructor is set to private so so nobody can create a new instance using new
private function __construct() {
// maybe set the db name here later
}
// Return DB instance or create intitial connection #return object (PDO) #access public
public static function getInstance() {
if (! self::$instance) {
self::$instance = new PDO ( 'mysql:host=localhost;dbname=Shopping;charset=utf8', 'root', 'vss0ftech' );
self::$instance->setAttribute ( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
echo 'connected';
} else
echo 'connection is already existed';
return self::$instance;
}
// Like the constructor, we make __clone private so nobody can clone the instance
PRIVATE FUNCTION __CLONE() {
}
}
product.php
here we can call the method as like this
class ProductInsert {
public function prdInsert(.....) {
$result_By_Vendor_And_Title = Connection::getInstance ()->query ( "select * from........)
}
}
Can anybody please guide me with a sample code to establish a database connection in php using singleton class.
class DatabaseSingleton
{
// [Singleton]
private static $instance = null;
public static function getInstance()
{
if (!self::$instance)
{
self::$instance = new self();
}
return self::$instance;
}
private function __clone(){}
// [/Singleton]
private $connection = null;
private function __construct()
{
$this->connection = mysql_connect('localhost','root','admin');
if ($this->connection)
{
mysql_select_db('my_database');
}
}
//
// crud operations go here.
//
}
$db = DatabaseSingleton::getInstance();
$db->SomeCRUDOperation();
Something like that perhaps? Very basic, but should give you a starting point.
That's how a singleton-pattern looks like:
<?php
class SingletonClass
{
static private $instance = null;
static public function getInstance()
{
if (null === self::$instance) {
self::$instance = new self;
}
return self::$instance;
}
private function __construct(){}
private function __clone(){}
}
$singletonClass = SingletonClass::getInstance();
Now you can put random functions and parameters in there that handle your DB-stuff. I hope that answers your question.
See the manual for an example on how to implement the Singleton pattern: http://www.php.net/manual/en/language.oop5.patterns.php
Then just establish the database connection in your class constructor.
I use something like this:
class DBConn
{
static private $_db = null; // The same PDO will persist from one call to the next
private function __construct() {} // disallow calling the class via new DBConn
private function __clone() {} // disallow cloning the class
/**
* Establishes a PDO connection if one doesn't exist,
* or simply returns the already existing connection.
* #return PDO A working PDO connection
*/
static public function getConnection()
{
if (self::$_db == null) { // No PDO exists yet, so make one and send it back.
try {
self::$_db = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_NAME, DB_USER, DB_PASS);
} catch (PDOException $e) {
// Use next line for debugging only, remove or comment out before going live.
// echo 'PDO says: ' . $e->getMessage() . '<br />';
// This is all the end user should see if the connection fails.
die('<h1>Sorry. The Database connection is temporarily unavailable.</h1>');
} // end PDO connection try/catch
return self::$_db;
} else { // There is already a PDO, so just send it back.
return self::$_db;
} // end PDO exists if/else
} // end function getConnection
} // end class DBConn
/**
* And you can use it as such in a class
* */
class Post {
public function __construct(){
$this->db = DBConn::getConnection();
}
public function getPosts()
{
try {
/*** The SQL SELECT statement ***/
$sql = "SELECT * FROM posts";
foreach ($this->_dbh->query($sql) as $row) {
var_dump($row);
}
/*** close the database connection ***/
$this->_dbh = null;
} catch (PDOException $e) {
echo $e->getMessage();
}
}
}
I am using something like below
class Database
{
private $_connection;
private static $_instance; //The single instance
private $_host = "HOST";
private $_username = "USERNAME";
private $_password = "PASSWORd";
private $_database = "DATABASE";
public static function getInstance() {
if(!self::$_instance) { // If no instance then make one
self::$_instance = new self();
}
return self::$_instance;
}
private function __construct() {
$this->_connection = new mysqli($this->_host, $this->_username,
$this->_password, $this->_database);
// Error handling
if(mysqli_connect_error()) {
trigger_error("Failed to conencto to MySQL: " . mysqli_connect_error(),
E_USER_ERROR);
}
}
// Magic method clone is for prevent duplication of connection
private function __clone() { }
public function getConnection() {
return $this->_connection;
}
}
$db = Database::getInstance();
$mysqli = $db->getConnection();
$sql_query = "SELECT foo FROM etc";
$result = $mysqli->query($sql_query);