PHP Singleton pattern, fatal error when calling getter - php

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();
}
?>

Related

Fatal error: Uncaught TypeError: Cannot assign PDO to property

Hey guys how can i assign PDO to my AbstractRepository class?
I got this error
#Fatal error: Uncaught TypeError: Cannot assign PDO to property #
class DataBase {
private $conn;
public static $instance;
private static $dsn = 'mysql:host=localhost;dbname=db';
private static $username = 'db';
private static $password = 'db';
public function __construct()
{
try {
$this->conn = new PDO(self::$dsn, self::$username, self::$password);
} catch (\PDOException $exception) {
echo 'Problem mit der Datenbankverbindung' . $exception->getMessage();
die();
}
}
public static function getInstance() {
if (!isset(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
public function getConnection() {
return $this->getInstance()->conn;
}
}
abstract class AbstractRepository{
protected DataBase $connection;
public function __construct(){
$this->connection = DataBase::getInstance()->getConnection();
}
}
This is how you can return the Value of type PDO
class DataBase extends PDO{
public static $instance;
private static $dsn = 'mysql:host=localhost;dbname=db';
private static $username = 'db';
private static $password = 'db';
public function __construct()
{
try {
parent::__construct = new PDO(self::$dsn, self::$username, self::$password);
} catch (\PDOException $exception) {
echo 'Problem mit der Datenbankverbindung' . $exception->getMessage();
die();
}
}
public static function getInstance() {
if (!isset(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
}
abstract class AbstractRepository{
protected DataBase $connection;
public function __construct(){
$this->connection = DataBase::getInstance();
}
}

How can I close connection from extended class

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.

PHP: Script showing parsing syntax error

I found an issue I can't seem to find a solution to. I am using a singleton class / method that return a single static PDO object. When I try to declare a static reference to the object (http://i.imgur.com/EhKZuVH.png), I get http://i.imgur.com/jUPMQrO.png . How would I go about fixing this?
Game Class:
<?php
include_once('functions.php');
include_once('database.php');
$_codeRegex = '^([a-zA-Z0-9]{4,7})$';
class Game
{
public $Id = "";
public $Name = "";
private static $connection = Database::Connect();
public function __construct($id, $name)
{
$this->Id = $id;
$this->Name = $name;
}
}
?>
My singleton Class:
<?php
require_once('config.php');
CONST CONNECTION_FORMAT = 'mysql:host=%1$s;dbname=%2$s;charset=utf8';
class Database
{
private static $cont = null;
public function __construct() {
exit('Initialize function is not excessible.');
}
public static function Connect()
{
if (self::$cont == null)
{
try
{
$pdoConstuct = sprintf(CONNECTION_FORMAT, DB_SERVER, DB_NAME);
self::$cont = new PDO($pdoConstuct, DB_USER, DB_PASS);
self::$cont->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
}
catch(PDOException $e) { return false; }
}
return self::$cont;
}
public static function Disconnect()
{
self::$cont = null;
}
}
?>
PHP is not Java where you can define property values like this.
What you can do here is simply put property initialization into the contructor, like this:
private static $connection;
public function __construct($id, $name)
{
$this->Id = $id;
$this->Name = $name;
self::$connection = Database::Connect();
}
When you define a class property in PHP you can not set its default value to instance of a class.

Database not selected php 5.3

I have a kind of connection that worked correctly in php 5.2, but now un updating to version 5.3 and it generates the error: "Database not selected". This is my script:
config.php :
$host = 'localhost'
$user = 'root'
$password = ''
$db = 'mydb'
Conf.class.php :
class Conf{
private $_userdb;
private $_passdb;
private $_hostdb;
private $_db;
static $_instance;
private function __construct(){
require 'config.php';
$this->_userdb=$user;
$this->_passdb=$password;
$this->_hostdb=$host;
$this->_db=$db;
}
private function __clone(){ }
public static function getInstance(){
if (!(self::$_instance instanceof self)){
self::$_instance=new self();
}
return self::$_instance;
}
public function getUserDB(){
$var=$this->_userdb;
return $var;
}
public function getHostDB(){
$var=$this->_hostdb;
return $var;
}
public function getPassDB(){
$var=$this->_passdb;
return $var;
}
public function getDB(){
$var=$this->_db;
return $var;
}
}
Db.class.php :
class Db {
private $server;
private $user;
private $password;
private $data_base;
private $link;
private $result;
static $_instance;
private function __construct() {
$this->setConnection();
$this->connect();
$this->result = null;
}
private function setConnection() {
$conf = Conf::getInstance();
$this->server = $conf->getHostDB();
$this->data_base = $conf->getDB();
$this->user = $conf->getUserDB();
$this->password = $conf->getPassDB();
}
private function __clone(){ }
public static function getInstance() {
if (!(self::$_instance instanceof self)){
self::$_instance=new self();
} return self::$_instance;
}
private function connect() {
$link=mysql_connect($this->server, $this->user, $this->password);
if ($link){
mysql_select_db($this->data_base,$link);
}
if (!$link){
die('Can not connect');
}else{
$this->link = $link;
}
}
}
Apparently Db.class class, does not operate the function getInstance () because no gets the data from Conf.class.
I need to change something in Db.class and Conf.class?
Probably a copy/paste issue but your db construct calls setConnection while your method name is setConexion. You also left out the semi colons in your config file.
Otherwise, your code ran fine for me. Might consider adding an error_reporting(E_ALL); and testing from the command line. You probably have an include file path issue and you are just not seeing the errors.

Establishing database connection in php using singleton class

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);

Categories