9

I am trying to connect to a database (MySQLi) just once, but am having problems doing so.

How do I make a connection global for the entire script? There are multiple files (index.php, /classes/config.class.php, /classes/admin.class.php, etc).

I've tried the following:

In: config.class.php

public static $config = array();
public static $sql;

function __construct() {
    // database
    db::$config['host'] = 'localhost';
    db::$config['user'] = '_';
    db::$config['pass'] = '_';
    db::$config['db'] = '_';

    // connect
    db::$sql = new mysqli(db::$config['host'], db::$config['user'], db::$config['pass'], db::$config['db']);
}

Again, in config.class.php

public function contectToDatabase($sql){
    $sql = new mysqli(db::$config['host'], db::$config['user'], db::$config['pass'], db::$config['db']);
    $this->sql = $sql;
}

I use the class with the following code: $config = new db();

I really am puzzled at how I'm to do this. Can anyone help?

--- Edit --- This is my new config.class.php file:

public static $config = array();
public static $sql;

private static $db;
private $connection;

public function __construct() {
    // database
    db::$config['host'] = '_';
    db::$config['user'] = '_';
    db::$config['pass'] = '_';
    db::$config['db'] = '_';
    // connect
    $this->connection = new mysqli(db::$config['host'], db::$config['user'], db::$config['pass'], db::$config['db']);
}
function __destruct() {
    $this->connection->close();
}
public static function getConnection() {
    if($db == null){
        $db = new db();
    }
    return $db->connection;
}

And this is how I'm loading it:

require_once("classes/config.class.php");
$config = new db();
$sql = db::getConnection();

However, running a real_escape_string results in the following errors:

Warning: mysqli::real_escape_string() [mysqli.real-escape-string]: Couldn't fetch mysqli in /home/calico/_/_.com/_/index.php on line 20

Warning: mysqli::query() [mysqli.query]: Couldn't fetch mysqli in /home/calico/_/_.com/_/index.php on line 28
Dharman
  • 30,962
  • 25
  • 85
  • 135
Peter
  • 238
  • 1
  • 2
  • 12
  • 1
    You could use the [singleton pattern](http://en.wikipedia.org/wiki/Singleton_pattern) – knittl Oct 17 '11 at 11:20
  • 1
    or you could learn Dependency Injection instead of using the [singleton antipattern](http://stackoverflow.com/questions/4595964/who-needs-singletons/4596323#4596323) – Gordon Oct 17 '11 at 11:26
  • 1
    Yeah… singletons always result in hot debates. I was just giving input and ideas – knittl Oct 17 '11 at 11:28
  • [SingletonVsJustCreateOne](http://butunclebob.com/ArticleS.UncleBob.SingletonVsJustCreateOne) – Gordon Oct 17 '11 at 11:37
  • Is there any way to have the connection as a global variable for each class? Eg: I set up a global variable called $sql, and set it to $sql = new mysqli(db::$config['host'], db::$config['user'], db::$config['pass'], db::$config['db']);? I don't want to repeat the database connectoin for every class. – Peter Oct 17 '11 at 12:16
  • @Peter you dont have to repeat it. Create the database instance once in your bootstrap file and then pass into the rest of the system via constructor injection to any component that needs it. Dont make it global. Dont make it available to every class there is. Just to those that need it via Dependency Injection. – Gordon Oct 17 '11 at 12:25
  • OK, I've added it to the config class, and have attempted to load it. However, there are errors (see the main post, under the ---edit--- line). Any ideas whats wrong? – Peter Oct 17 '11 at 12:58

1 Answers1

18

Personally, I use a singleton class. Something like this:

<?php

class Database {

    private static $db;
    private $connection;

    private function __construct() {
        $this->connection = new MySQLi(/* credentials */);
    }

    function __destruct() {
        $this->connection->close();
    }

    public static function getConnection() {
        if (self::$db == null) {
            self::$db = new Database();
        }
        return self::$db->connection;
    }
}

?>

Then just use $db = Database::getConnection(); wherever I need it.

Reed
  • 14,703
  • 8
  • 66
  • 110
daiscog
  • 11,441
  • 6
  • 50
  • 62
  • 1
    Your Singleton can be serialized and cloned which means it does not ensure there is only one instance. – Gordon Oct 17 '11 at 11:32
  • OK, I've added it to the config class, and have attempted to load it. However, there are errors (see the main post, under the ---edit--- line). Any ideas whats wrong? – Peter Oct 17 '11 at 12:58
  • 1
    @Peter Don't add it to another class. This is a singleton class that should be stand-alone and should not have a public constructor. Just use `$db = Database::getConnection();` to get an open MySQLi instance wherever you need it. – daiscog Oct 17 '11 at 13:25
  • @Gordon Yes, this is just a quick example; hence "Something like this" – daiscog Oct 17 '11 at 13:26
  • Could I implement PDO with this? – AGDEV May 25 '13 at 12:44
  • This doesn't work for me. The database connection looks fine before returning it (in `getConnection()`) , but the calling method using `Database::getConnection();` gets an empty connection object. – Gruber Jun 22 '15 at 06:19