6

Should have asked someone this a long time ago.

What is the best way to use other classes within another class?

For instance, lets say I have an application class:

class Application
{
    public function displayVar() {
        echo 'hello world';
    }
}

and a database class

class Database
{
    // connects to db on construct
    public function query() {
        // queries db
    }
}

now, i want to add a function to my application class that uses a function from the db class

class Application
{
    public function displayVar() {
        echo 'hello world';
    }
    public function getVar() {
        global $db;
        $sql = foo;
        $db->query($sql);
    }
}

so then I have

$db = new Database();
$app = new Application();
$app->getVar('var');

Is there a better way of doing this? Really what I am looking for is the standard way of doing it, not another way of rigging it.

2
  • 1
    Yeah, that question is delving deep into this. You might want to check it out Citizen. Commented Jan 7, 2010 at 3:29
  • Na, the answer here is exactly what I was looking for. Commented Jan 7, 2010 at 4:58

3 Answers 3

12

There are a couple of ways of doing that. Global variables is certainly one way and the most looked down upon too. You can create a Singleton and all other classes that need database access would call upon this singleton.

final class Database {
    private static $connection;

    public static function getInstance() {
        if(self::$connection == NULL) {
            self::$connection = // init your database connection
        }
        return self::$connection;
    }
}

And use this database connection object in whatever class needs it.

class Application {
    public function displayVar() {
        echo 'hello world';
    }
    public function getVar() {
        $db = Database::getInstance();
        $sql = foo;
        $db->query($sql);
    }
}

This is all well for a start and a great step beyond using global variables, but you can do better with Dependency Injection. Dependency Injection is a simple concept that if a class has any external dependencies, such as the database connection in your example, you explicitly pass those to the needy class in its constructor or a method. So the new code would look something like Jonathan's solution. A major advantage of using dependency injection is in unit testing, where you can easily replace this actual database object with a mock object and pass it to whoever needs it.

class Application {
    private $db;

    public function __construct(Database $db) {
        $this->db = $db;
    }

    public function displayVar() {
        echo 'hello world';
    }

    public function getVar() {
        $sql = foo;
        $this->db->query($sql);
    }
}

For smaller projects, you can easily do it yourself. For large projects, there are various DI frameworks available for PHP

Sign up to request clarification or add additional context in comments.

1 Comment

You might want to put a little more emphasize on your second solution as the singleton approach really is prone to a huge load of trouble. It's generally considered as a bad thing (but sadly still widely used).
3

$db could be a property of your Application class. Any reference to it from within an instance of Application would be done via $this - $this->db

class Application {

  private $db = null;

  public function setDB($name) {
    $this->db = new Database($name);
  }

}

1 Comment

Yea, I got that but then what about other classes? Like if i had a user.class.php or an admin.class.php, I'd still have to globalize the class to use it.
1

Include the class file (or set up autoinclude) in each PHP file that needs the class in question. Then instantiate it as needed.

If you need to have a "common" instance of an object, you can look at the Singleton and Factory patterns:

Singleton Pattern Factory Pattern

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.