Connect DB class in more file - php

Goodmorning everyone.
I have 3 files: config_db.php, module.php and index.php
I need db connection to hold for many module.php.
so I would like on index to call the class of module.php and the module.php to call config_db.
I give a practical example:
index.php:
require_once('../component/command/module.php');
$boards= new command();
$result = $boards->getAllOutputs();
module.php:
class command extends DB {
protected static $database = 'db';
function getAllOutputs() {
$sql = "SELECT * FROM outputs";
$db = Main::getInstance();
$obj = $db->fetch_single_row($sql, $data);
var_dump($obj);
}
}
config_db.php:
abstract class DB
{
protected static $instance;
protected $db;
protected static $host = 'localhost';
protected static $user = 'root';
protected static $pass = 'pw';
protected static $database='database';
public static function getInstance()
{
if (!isset(self::$instance)) self::$instance = new static();
return self::$instance;
}
protected function __construct()
{
$this->db = new PDO(sprintf('mysql:host=%s;dbname=%s', static::$host, static::$database), static::$user, static::$pass);
$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
public static function db()
{
return static::getInstance()->db;
}
public function fetch_single_row($sql, $data)
{
if( $data !== null )
$data = array_values( $data ); // Incase it's an associative array
$sel = self::db()->prepare( $sql );
$sel->execute( $data );
$sel->setFetchMode( PDO::FETCH_OBJ );
$obj = $sel->fetch();
return $obj;
}
}
when opening the index the error is the following:
( ! ) Fatal error: Uncaught Error: Call to protected DB::__construct() from invalid context in C:\wamp64\www\xxx\tmpl\index.php on line 706
( ! ) Error: Call to protected DB::__construct() from invalid context in C:\wamp64\www\xxx\tmpl\index.php on line 706
could you help me?

Related

PHP Singleton pattern, fatal error when calling getter

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

PDO DB connection issues

I have changed the code a bit, but nothing changed. I'm obviously not able to use PDO correctly.
So, the db connection is here:
class Database {
private static $instance = null;
private function __construct(){}
public static function getInstance() {
if(is_null(self::$instance)){
self::$instance = new PDO("mysql:host = localhost, dbname = elektro", "root", "");
}
return self::$instance;
}
}
This class deals with the DB:
abstract class ActiveRecord {
private static $conn;
public static function getAll(){
$conn = Database::getInstance();
$table = static::$table;
$class = get_called_class();
$q = self::$conn->query("select * from {$table}");
$res = $q->fetchAll();
return $res;
}
}
And this one is supposed to fetch all rows from one table:
class Autor extends ActiveRecord {
public static $table = "autor";
}
$conn = Database::getInstance();
$allAutors = Autor::getAll();
print_r($allAutors);
This results in Fatal error: Call to a member function query() on null

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.

Call to a member function on a non-object

I am new to php oop , so struggling a bit .
i have a database connection class viz :
class config{
protected $HOST = "localhost";
protected $USERNAME = "something" ;
protected $PASSWORD = "something";
protected $DATABASE = "something";
// Constructor - open DB connection
function __construct() {
try {
$this->db = new mysqli($this->HOST, $this->USERNAME, $this->PASSWORD, $this-
>DATABASE);
$this->db->autocommit(FALSE);
}
catch(Exception $e)
{
if($this->db->connect_errno > 0){
echo 'Caught exception: ', $e->getMessage(), "\n";
}
}
}
// Destructor - close DB connection
function __destruct() {
$this->db->close();
}
}
$api = new Config();
Now i have another class from which i need to perform some tasks ...but i get FATAL error .
second class :
class Myclass extends config {
function __construct(){}
public function myfunction()
{
try{
$stmt = $this->db->stmt_init(); /* Error here : Fatal error: Call to a member
function stmt_init() on a non-object */
$query = "SELECT ABC FROM table " ;
$stmt = $this->db->prepare($query); /* Error here : Fatal error: Call to a member
function prepare() on a non-object */
}
catch(){}
}
}
Please guide me with proper remedial code snippet
In your child class, you need to call the parent constructor. PHP won't automatically call parent constructor's when a child class is instantiated.
class Myclass extends config {
function __construct($h, $u, $p, $d){ parent::__construct($h, $u, $p, $d); }
Also, you don't have a $db property in the parent class, so add that
class config{
protected $db;
protected $HOST = "localhost";
protected $USERNAME = "something" ;
protected $PASSWORD = "something";
protected $DATABASE = "something";
Edit: Dependency Injection approach:
class config{
public $HOST = "localhost";
public $USERNAME = "something" ;
public $PASSWORD = "something";
public $DATABASE = "something";
}
class Myclass
{
protected $db;
function __construct($db)
{
$this->db = $db;
}
public function myfunction()
{
// do whatever with $this->db
}
}
$config = new Config();
try
{
$db = new mysqli($config->HOST, $config->USERNAME, $config->PASSWORD, $config->DATABASE);
$db->autocommit(FALSE);
}
catch(Exception $e)
{
if($db->connect_errno > 0){
echo 'Caught exception: ', $e->getMessage(), "\n";
}
}
$myclass = new Myclass($db);
Have a look into Dependency Injection. This is a favorable approach for dealing with classes that need access to a database. Instead of having all your classes extend the database, just pass the datsbase object as a parameter when creating new classes (that need the db).
Your derived class constructor is not calling the base constructor, so $this->db does not have the value it's supposed to. In PHP you must do this explicitly.
In this particular case, you should remove the derived constructor altogether since it's not doing anything. This will let PHP use the base constructor directly.

Using PDO database class within other PHP classes

I have a database class that uses PDO. Here's a portion example of it:
class db {
private $host;
private $username;
private $password;
private $con;
private $pdo;
public function __construct( $database = "dnname" )
{
$this->host = "localhost";
$this->username = "username";
$this->password = "pass";
$conStr = "host={$this->host};dbname={$database}";
try {
$this->pdo = new PDO( "mysql:$conStr", $this->username, $this->password );
$this->pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
}
catch( PDOException $e ) {
echo "error ". $e->getMessage();
}
}
public function fetch_single_row($sql, $data)
{
if( $data !== null )
$data = array_values( $data ); // Incase it's an associative array
$sel = $this->pdo->prepare( $sql );
$sel->execute( $data );
$sel->setFetchMode( PDO::FETCH_OBJ );
$obj = $sel->fetch();
return $obj;
}
I would like to use this class and its functions (it has more than I've included) inside other classes.
I have tried many many different things, but the only thing that works so far is starting a new instance of db in every new class which I think is bad practice. For instance:
class cms {
function cms(){
$this->db = new db();
}
function is_admin($id) {
if($this->db->fetch_single_row("SELECT id FROM user WHERE id = ? LIMIT 1", array($id))){
return true;
} else {
return false;
}
}
in my index.php, I include these classes and use them:
include("db.class.php");
include("cms.class.php");
$cms = new cms();
if($cms->is_admin($id)){
//code here
}
What is the correct way to accomplish this?
Take a look into the Singleton Design Pattern, it works great for a DB class
I used to use a class like this for quite a while
abstract class DB
{
protected static $instance;
protected $db;
protected static $host = 'host';
protected static $user = 'user';
protected static $pass = 'pass';
protected static $database;
public static function getInstance()
{
if (!isset(self::$instance)) self::$instance = new static();
return self::$instance;
}
protected function __construct()
{
$this->db = new PDO(sprintf('mysql:host=%s;dbname=%s', static::$host, static::$database), static::$user, static::$pass);
$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
public static function db()
{
return static::getInstance()->db;
}
public function fetch_single_row($sql, $data)
{
if( $data !== null )
$data = array_values( $data ); // Incase it's an associative array
$sel = self::db()->prepare( $sql );
$sel->execute( $data );
$sel->setFetchMode( PDO::FETCH_OBJ );
$obj = $sel->fetch();
return $obj;
}
}
I would then extend that class for each different database I would need to connect to
class Main extends DB
{
protected static $database = 'db';
}
You can then use the class like this
$db = Main::getInstance();
$obj = $db->fetch_single_row($sql, $data);

Categories