2

This is my general php page:

<?php
require_once('includes.php');
require_once('cms.class.php');
.....
rest of the page
?>

in includes.php an pro object called $db is initiated which I want to use in the class specified in the cms.class.php

includes.php:

$db = new PDO('mysql:host=localhost;dbname=xxxxx','xxxxx','xxxxxx'); 
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);

How can I use this database object in my classes without having multiple places where my credentials are stored?

stUrb
  • 6,612
  • 8
  • 43
  • 71
  • inject the `$db` object in your class through the cms class constructor, or have a registry object that you pass. – Lawrence Cherone Apr 13 '12 at 18:23
  • Is that the full includes.php ? It's my understanding that anything "in-line" will be executed. Therefore, the $db should be accessible. – kevingreen Apr 13 '12 at 18:23

2 Answers2

3

You need want a dependency manager or a bootstrapper or whatever you want to call it.

class Dependency_Manager {

    private $db;

    public function __construct($settings) {
        $this->db = new PDO('mysql:host=localhost;dbname=' . settings["dbname"],settings["username"],$setings["password"]); 
        $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
        $db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
    }

    public function getDB() {
        return $db;
    }

}

class CMS {
    public function __construct(PDO $db) {
        /* .. */
    }
}

$setting = array(/* etc */);

$dm = new Dependency_Manager($settings);
$cms = new CMS($dm->getDB());

This approach scales very well and can handle any dependecy. It also aims to put all the settings in one place so you don't have configuration settings littered everywhere. The $dm is the only one who knows the settings, if you need to construct something based on the settings, put it in the $dm.

Halcyon
  • 57,230
  • 10
  • 89
  • 128
  • This sounds like a great solution; but also a lot of code compared to 'simple' injection of the $db object in the new class construct. What else can you add to the $dm? Just to make the extended code 'worth' the place? Is it a good place to add a good logging function? Do you have some examples what you can add in the dm? – stUrb Apr 13 '12 at 18:58
  • 1
    Anything that is like a _resource_. A database (obviously). Loggers (they usually have settings, write to _this_ file or mail to _that_ address). Session manager etc. It is a lot of code if you just need to construct one object and pass in a database, but if your applications is more complicated it will pay off quickly. Basically the only file you want to 'run' is this bootstrap file, all the other files should be classes. – Halcyon Apr 13 '12 at 19:01
1

There are 2 ways that you could go about this.

The first way, injection, is growing in popularity. Injection means you would supply $db to your class. You could do something like this.

Injection:

class CMS_class {
  protected static $db;

  public function __construct($db) {
    if ( ! isset(self::$db))
      self::$db = $db;
  }

  public function __get($name) {
    if ($name === 'db')
      return self::$db;
  }
}

Now when you construct the CMS class you pass it the $db variable which is accessible via ->db, but there is only one instance.

The second method would be to call it globally in every function you use it.

Global:

class CMS_class {
  function hello_world() {
    global $db;
    var_dump($db);
  }
}

This way is losing popularity because globals are generally frowned upon and you will have to declare it in every function that you need $db.

There are other good answers out there that relate to your question. How can I use "Dependency Injection" in simple php functions, and should I bother?

Community
  • 1
  • 1
None
  • 5,491
  • 1
  • 40
  • 51