Database Singleton Error - php

I'm getting this Error by using this singleton class. Please explain me what i'm doing wrong in that? i'm trying to get the sqli object through constructor.
Fatal error: Call to private DB::__construct() from invalid context in C:\xampp\htdocs\docs\users.php on line 20
<?php
class DB
{
#############################
##### Define Connection ####
#############################
const HOST = 'localhost';
const USER = 'root';
const PASSWORD = '';
const DATABASE = 'ali';
#############################
// Data Member For MySQLi Database Connection
private static $mysqli = NULL;
// Database Connection
private function __construct()
{
#self::$mysqli = new mysqli(self::HOST, self::USER, self::PASSWORD, self::DATABASE);
if (self::$mysqli->connect_error) {
throw new Exception("<b>Database Connect Error: </b>" . self::$mysqli->connect_error);
}
if (self::$mysqli->error) {
throw new Exception("<b>Database Select Error: </b>" . self::$mysqli->error);
}
echo "<span style='color: green; font-size: 18px; font-weight: bold'>Connected</span>
<br>"; // For testing //
return self::$mysqli;
}
// Class Level Static Function to Get Database Connection
public static function get_connection()
{
if ( ! isset(self::$mysqli) )
{
self::$mysqli = new self();
}
return self::$mysqli;
}
}
?>
my 2nd file where i'm using this class
<?php
require_once 'DB.php';
class users extends DB
{
public function get_results()
{
$sqli = DB::get_connection();
$user_data = $sqli->query("SELECT * FROM `users`");
while($row = $user_data->fetch_object())
{
echo $row->name . "<br>";
}
}
}
$user = new users;
try {
$user->get_results();
} catch (Exception $e) {
echo $e->getMessage();
}
?>

if you're not aiming to build that typical database connection singleton then following code will achieve what you want
class DB
{
const HOST = 'localhost';
const USER = 'root';
const PASSWORD = '';
const DATABASE = 'yourdb';
private static $mysqli = null;
private function __construct() {
//an empty private constructor to prevent creating instances of this class
}
public static function get_connection() {
if(!self::$mysqli) {
//create mysqli object here and return instead of (typically returned) self instance
$conn = new mysqli(self::HOST, self::USER, self::PASSWORD, self::DATABASE);
if($conn->connect_error) {
throw new Exception("<b>Database Connect Error: </b>" . $conn->connect_error);
}
if($conn->error) {
throw new Exception("<b>Database Select Error: </b>" . $conn->error);
}
self::$mysqli = $conn;
}
return self::$mysqli;
}
}
user class doesn't need any changes, except for removing extends DB, to eliminate the error.
Update
class DB
{
const HOST = 'localhost';
const USER = 'root';
const PASSWORD = '';
const DATABASE = 'yourdb';
private $mysqli = null;
private function __construct() {
$conn = new mysqli(self::HOST, self::USER, self::PASSWORD, self::DATABASE);
if($conn->connect_error) {
throw new Exception("<b>Database Connect Error: </b>" . $conn->connect_error);
}
if($conn->error) {
throw new Exception("<b>Database Select Error: </b>" . $conn->error);
}
$this->mysqli = $conn;
}
/**
* #return DB
*/
public static function get_connection() {
/**
* #static $DB DB a static variable that is not class member but will be _shared_ across all calls to DB::get_connection()
*
* WTF? http://stackoverflow.com/questions/6601027/php-and-static-variables-in-object-member-functions
*/
static $DB = null;
if($DB == null) {
$DB = new DB();
}
return $DB;
}
/**
* A wrapper for internal database object/connection/resource's query method
* #param $sql String the sql query
*
* #return bool|mysqli_result
*/
public function query($sql) {
return $this->mysqli->query($sql);
}
}

Related

Passing db object to php class oop style does not work

Simple classes using oop php, trying to pass db object (from db class) to another class ( category class ) so i can get the content from db .
db class db.php
class db {
//put your code here
private $hostname = "127.0.0.1";
private $dbname = "php_oop_crud";
private $username = "root";
private $password = "";
public $conn;
public $status = 0;
public function getConnection() {
$this->conn = null;
try {
$this->conn = new PDO("mysql:host:$this->hostname;dbname=$this->dbname", $this->username, $this->password);
// this return null if unsccessfull
$this->status = $this->conn->getAttribute(PDO::ATTR_CONNECTION_STATUS);
if ($this->status) {
echo "connected to db : " . $this->status;
return $this->conn;
}
} catch (PDOException $ex) {
echo "Can't connect to db " . $this->status;
error_log("Ayman :: {{$ex->getMessage()}} - {{$ex->getFile()}} - {{$ex->getLine()}}");
return $this->conn;
}
}
}
pass db object to category class in index.php
// Create db connection pass it to product and category objects
$databaseConn = new db();
$db = $databaseConn->getConnection();
// create object and send database object to class
// now we need to call the function who crearte tha actual connection getConnection();
$category= new category($db);
$category->read();
category class category.php
<?php
class category {
//put your code here
private $databaseConn;
private $tabel_name = 'categories';
public $id;
public $name;
public function __construct($db) {
$this->databaseConn = $db;
}
public function read() {
$sql = 'SELECT * FROM categories';
$query = $this->databaseConn->prepare($sql);
$isok = $query->execute();
$row= $query->rowCount();
echo "row : " . $row;
var_dump($row);
echo "isok : " . $isok;
var_dump($isok);
if ($isok) {
echo "the red process is done and ok <br/> category table";
} else {
echo "Cant get category ";
var_dump($isok);
}
}
}
Now the var_dump($row) and var_dump($isok); are always false , mean while I can connect successfully to db
Credit for #ishegg , be careful when you construct your PDO .
// this will NOT work
$this->conn = new PDO("mysql:host:$this->hostname;dbname=$this->dbname", $this->username, $this->password);
// this will Work
$this->conn = new PDO("mysql:host=".$this->hostname.";dbname=".$this->dbname, $this->username, $this->password);

Call to undefined method in php

Here is my config.php
<?php
define('DB_HOST', 'localhost');
define('DB_NAME', 'xxxx');
define('DB_USER', 'xxxx');
define('DB_PASS', 'xxxx');
?>
And It is DB.php
<?php
include 'config.php';
class DB {
public static $pdo;
public static function connection(){
if (!isset(self::$pdo)) {
try {
self::$pdo = new PDO('mysql:host='.DB_HOST.'; dbname ='.DB_NAME,DB_USER, DB_PASS);
}catch(PDOException $e){
echo $e->getMessage();
}
}
return self::$pdo;
}
public static function prepareOwn($sql){
return self::connection()->prepare($sql);
}
}
?>
3rd file is Student.php
<?php
include 'DB.php';
class Student {
public $table = 'student_info';
public function readAll(){
$sql = "SELECT * FROM $this->table";
$stmt = DB::prepareOwn($sql);
$stmt->execute();
return $stmt->fetchAll();
}
}
?>
But When I try to access readAll() from index.php using spl_autoload_register() Then I can see Fatal error: Call to undefined method DB::prepareOwn()
Can anyone help me to solve the problem??
Many thanks.
Sahidul
i copied your code into mine and saw your error. but as i guessed, first you will get an error with this line inside db.php:
return self::$pdo->prepare($sql);
Fatal error: Call to a member function prepare() on null
where prepare function came from? $pdo is just a static property in this class and it doesn't have a function called prepare! fix this line
Updated
the problem is you forgot to call connection method inside your prepareOwn. so your new prepareOwn function should be:
public static function prepareOwn($sql) {
self::connection();
return self::$pdo->prepare($sql);
}
i hope this code will work for you
class MySQLDatabase {
// Class attributes
private $host_name = "localhost";
private $database_name = "XXXXXXX";
private $database_username = "XXXXXXX";
private $database_password = "XXXXXXX";
private $is_connected;
private $connection;
private $statement ;
// construct
public function __construct() {
$this->open_connection();
}// End of construct
// connection method
public function open_connection() {
try {
$this->is_connected = TRUE ;
// PDO Connection
$this->connection = new PDO("mysql:host=".$this->host_name.";dbname=".$this->database_name.";charset=utf8",$this->database_username,$this->database_password);
// Error reporting
$this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->connection->setAttribute(PDO::ATTR_EMULATE_PREPARES,FALSE);
} catch(PDOException $errors) {
$this->is_connected = FALSE ;
self::catch_errors($errors);
}
}// End of open connection method
// Get connection method
public function connection(){
return $this->connection ;
}
// Close connection method
public function close_connection() {
$this->connection = null;
}// End of close connection method
private static function catch_errors($errors) {
echo("<h4><p>" . $errors -> getMessage() . "</p></h4>");
die();
}
// query method
public function query($sql){
return $this->statement = $this->connection->prepare($sql);
}
}// End of database class
$database = new MySQLDatabase();
class Student {
protected static $table = 'My_table';
public function readAll(){
global $database;
try{
$sql = "SELECT * FROM ". self::$table;
$stmt = $database->query($sql);
$stmt->execute();
return $stmt;
}catch(PDOException $error){
echo("<h4><p>" . $errors -> getMessage() . "</p></h4>");
die();
}
}
}
$c = new Student();
$s = $c->readAll();
$stmt = $s->fetchAll(PDO::FETCH_ASSOC);
foreach($s as $v){
var_dump($v);
}

PHP mysqli query: couldn't fetch mysqli

I am trying to make a db connection and check a table for existing data. However I recieve this error and I am unable to find the cause:
Warning: mysqli::query(): Couldn't fetch mysqli in
/usr/share/nginx/www/me/container/class_lib.php on line
33 Warning: mysql_fetch_assoc() expects
parameter 1 to be resource, null given in
/usr/share/nginx/www/me/container/class_lib.php on line
97
class dbHandler {
static $dbObj = null;
protected $db_host = 'localhost'; #db host
protected $db_username = 'user'; #db username
protected $db_password = 'password'; #db password
protected $db_name = 'db'; #db name
function __construct()
{
# connect if not connected
if(self::$dbObj === null)
{
self::$dbObj = new mysqli($this->db_host, $this->db_username, $this->db_password, $this->db_name)
or die($this->dbObj->error);
}
mysqli_set_charset(self::$dbObj, "utf8");
}
// query: query the db
public function query($query)
{
return self::$dbObj->query($query);
}
}
/*
class userLogin
create user login
*/
class userLogin {
private $username;
private $password;
function __construct($username, $password) {
$this->_dbConn = new dbHandler();
$this->username = $username;
$this->password = $password;
}
public function verifyCredentials() {
if($this->verifyUsername())
{
} else {
exit;
}
if($this->verifyPassword())
{
} else {
exit;
}
}
private function verifyUsername() {
if(!(preg_match('/[^a-z_\-0-9]/i', $this->username)))
{
return true;
}
}
private function verifyPassword() {
$query = "SELECT * FROM tbl_user";
$result = $this->_dbConn->query($query);
$row = mysql_fetch_assoc($result);
var_dump($row);
}
}
What am I doing wrong here?
All your wrapper is over a mysqli object oriented way, and suddenly you have this line?
$row = mysql_fetch_assoc($result);
You have to use the fetch_assoc from the mysqli result object
$result->fetch_assoc()
Your SQL query is clearly failing. Why you have a function query to call a query I don't know but I have a feeling that is the route cause of your issue. You would be better off with something like this:
class dbHandler extends mysqli {
protected $db_host = 'localhost'; #db host
protected $db_username = 'user'; #db username
protected $db_password = 'password'; #db password
protected $db_name = 'db'; #db name
function __construct()
{
parent::__construct($this->db_host, $this->db_username, $this->db_password, $this->db_name);
if($this->connect_errno)
{
trigger_error('Unable to connect to the database [' . $this->connect_errno . ']: ' . $this->connect_error, E_USER_ERROR);
}
}
public function __destruct()
{
parent::close();
}
}
/*
class userLogin
create user login
*/
class userLogin {
private $username;
private $password;
function __construct($username, $password) {
$this->_dbConn = new dbHandler();
$this->username = $username;
$this->password = $password;
}
public function verifyCredentials() {
if($this->verifyUsername())
{
} else {
exit;
}
if($this->verifyPassword())
{
} else {
exit;
}
}
private function verifyUsername() {
if(!(preg_match('/[^a-z_\-0-9]/i', $this->username)))
{
return true;
}
}
private function verifyPassword() {
$query = "SELECT * FROM tbl_user";
$result = $this->_dbConn->query($query);
if($this->_dbConn->errno)
{
trigger_error('Error fetching users from table. Query: ' . $query . '. Error: ' . $this->_dbConn->error);
return false;
}
if($result->num_rows)
{
while($row = $result->fetch_assoc())
{
var_dump($row);
}
}
}
}
Let me know how you get on with that.
So... I never gave the mysql user from localhost any grants. Only from the remote LAN. Problemo solved.
Probably you are closing the connection too early? DBConnect->close();?
so, if you try to execute any query after that, you will get an error!

ADODB Multiple Databases

I am using adodb for my database operations and here i am facing a problem that i can't add tow or 3 databases in my script i am using 3 databases but its not working properly need help in this situation.
myadodb connection file:
<?php
include_once("/adodb/adodb.inc.php");
include_once("/adodb/adodb-exceptions.inc.php");
class ADb {
function ADb()
{
global $dbserver;
global $dbuser;
global $dbpass;
global $database;
$dbuser = "";
$dbpass = "";
$dbserver = "";
$database = "";
$this->conn1 = &ADONewConnection('mysql');
$this->conn1->PConnect($dbserver, $dbuser, $dbpass, $database);
}
function query($sql)
{
try
{
$Result = $this->conn1->Execute($sql);
}
catch (exception $e)
{
echo $e->msg;
}
}
}
?>
I have created 3 files for 3 databases connections
This is a quick class that I made that should allow you to connect to 3 databases using adoDB:
class Data {
private static $_dbOne = null;
private static $_dbTwo = null;
private static $_dbThree = null;
protected function __construct() {
}
/**
* This function returns the database connection object
* #return Object Database Connection
*/
public static function dbOne() {
include_once(LIBRARY_PATH.'adodb5/adodb.inc.php');
if (null === self::$_dbOne) {
$_connOne = 'mysql://username:password#www.server.com/database';
self::$_dbOne = &ADONewConnection($_connOne);
if (self::$_dbOne==false) { die('Could not connect to the database.'); }
}
return self::$_dbOne;
}
/**
* This function returns the database connection object
* #return Object Database Connection
*/
public static function dbTwo() {
include_once(LIBRARY_PATH.'adodb5/adodb.inc.php');
if (null === self::$_dbTwo) {
$_connTwo = 'mysql://username:password#www.server.com/database';
self::$_dbTwo = &ADONewConnection($_connTwo);
if (self::$_dbTwo==false) { die('Could not connect to the database.'); }
}
return self::$_dbTwo;
}
}
/**
* This function returns the database connection object
* #return Object Database Connection
*/
public static function dbThree() {
include_once(LIBRARY_PATH.'adodb5/adodb.inc.php');
if (null === self::$_dbThree) {
$_connThree = 'mysql://username:password#www.server.com/database';
self::$_dbThree = &ADONewConnection($_connThree);
if (self::$_dbThree==false) { die('Could not connect to the database.'); }
}
return self::$_dbThree;
}
}
Here is an example of how you would use this class:
$sql = "SELECT * FROM *";
$results1 = Data::dbOne()->Execute($sql);
$results2 = Data::dbTwo()->Execute($sql);
$results3 = Data::dbThree()->Execute($sql);

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