views:

1644

answers:

5

I have a database class, which an instance is declared in the main index.php as

$db = new Database();

Is there a way for the $db variable to be globally recognized in all other classes without having to declare

global $db;

in the constructor of each class?

+12  A: 

No. You have to declare Global $db in the constructor of every class.

or you can use the Global array: $_GLOBALS['vars'];

The only way to get around this is to use a static class to wrap it, called the Singleton Method (See Here for an explanation). But this is very bad practice.

  class myClass
   {
    static $class = false;
    static function get_connection()
    {
     if(self::$class == false)
     {
      self::$class = new myClass;
     }
     else
     {
      return self::$class;
     }
    }
    // Then create regular class functions.
   }

The singleton method was created to make sure there was only one instance of any class. But, because people use it as a way to shortcut globalling, it becomes known as lazy/bad programming.

StackOverflow Knowledge
How to Avoid Using PHP Global Objects
Share Variables Between Functions in PHP Without Using Globals
Making a Global Variable Accessible For Every Function inside a Class
Global or Singleton for Database Connection

Chacha102
Why the downvote?
Chacha102
I freaking said that the Singleton method wasn't the right answer to this. But I included it because it 'technically' can be used.
Chacha102
I wasn't the down vote, thanks for letting me know - I want to avoid bad practices.
Dave Hunt
I updated with some other links you might look into. I actually do support using Singleton for a database class, but you still should global it.
Chacha102
Hmm which method do you recommend for including a database class within every class in the application easily? This singleton method still doesn't make the $db variable global within other classes.
Dave Hunt
I would suggest just Globaling everything. It is really simple and clear, which is important for debugging.
Chacha102
I know it isn't the answer you are looking for, but it is really the best way.
Chacha102
So I should just do what I had in my original question? Use a regular variable and make it global wherever it is needed?
Dave Hunt
Yep. Another method that I use is create a helper class that does some stuff like globalling in the constructor, and then extend all my main classes with it. But, yeah, just create a regular variable and global it. That is why the global keyword was created.
Chacha102
+1  A: 

you could use

$GLOBALS['db']->doStuff();

or alternatively using some kind of singleton access method

Database::getInstance()->doStuff();
Paul Dixon
Are either of those methods bad practices? Is the best practise to just declare the database class as global within each class?
Dave Hunt
A: 

You could use a Registry class to store and retrieve your Database instance.

class Registry
{
    protected static $_data = array();

    public static function set($key, $value)
    {
        self::$_data[$key] = $value;
    }

    public static function get($key, $default = null)
    {
        if (array_key_exists($key, self::$_data)) {
            return self::$_data[$key];
        }

        return $default;
    }
}

Registry::set('db', new Database());
$db = Registry::get('db');
Philippe Gerber
That is basically a singleton class for data....
Chacha102
so is $GLOBALS ...
Philippe Gerber
Except `$GLOBALS` and the `global` keyword are built into the language, and are therefore fast and known to everyone. Your registry class is not, and adds no extra functionality. Some sort of `Options` class might be useful for storing app options, but even that could probably replaced by an associative array.
Samir Talwar
This basic construct adds no extra functionality. But you're free to add. For example debugging or logging features. Performance is no argument, sorry ... we're in OO context here. And as soon as you use third-party software you want to encapsulate your data. See Zend_Registry in Zend Framework.
Philippe Gerber
A: 

Why not create a class that contains the global $db; in it's constructor, then extend all other classes from this?

Question Mark
A: 

I do it a little different. I usually have a global application object (App). Within that object I do some basic initialization like creating my db objects, caching objects, etc.

I also have a global function that returns the App object....thus (application object definition not shown):

define('APPLICATION_ID', 'myApplication');

${APPLICATION_ID} = new App;

function app() {
    return $GLOBALS[APPLICATION_ID];
}

So then I can use something like the following anywhere in any code to reference objects within the global object:

app()->db->read($statement);
app()->cache->get($cacheKey);
app()->debug->set($message);
app()->user->getInfo();

It's not perfect but I find it to make things easier in many circumstances.

conceptDawg