Understanding Class and Method Scope

I have a file, index.php. In this file I include a database class called db.php. In the db.php file I stat a

[php]
db = new db
[/php]

I have a __constructor function that issues a connection to mysql. It works fine for index.php

Now here is the issue, if I include anything else in the index.php, I have to re include the database class to get yet another connection for that include file, within that file.

Is there a way around this, or some how to make a class and its methods global? Without rewriting my whole app.

Your problem has multiple solutions.

The first is obvious: declare your DB object globally (global $DB; $DB = new DB();), which will allow you to use the following: global $DB; $DB->connect(); or otherwise.

The other solution is a design pattern called the singleton pattern. It works stupidly well but has a few drawbacks. I’ll write a tutorial on design patterns soon, so if you want to know more, stay tuned. This specific one is characterised by three properties:

  • Its constructor is private. This prevents the class from being instantiated from outside itself
  • There can only be one instance of the class
  • It is located using either a directory locator, Inversion of Control or through knowing the exact class name (bad)

The pattern is pretty simple and summarized to this:
[php]<?php
class MySingleton {
private static $instance;
private function __construct() {
// Your constructor
}
public static function getInstance() {
if (!isset(static::$instance)) {
static::$instance = new self();
}
return static::$instance;
}
}[/php]

What you then do is, instead of using the keyword new to create an instance, you call getInstance(). If it is the first time you call it, it will initialize an instance. Otherwise, it will return it.

This is particularly potent for database connections, as it allows you to easily keep one connection running.

Perfect, thank you!

Yeah I can see where I can get in some trouble using the singleton approach with my current app. I will try global for now.

I appreciate your help.

There is no real “trouble”. It just comes and bites you in the ass when you want to unit-test code that uses it, as there is no way to mock it without replacing it with something with the exact same name.

Other than that, it works relatively fine and is a neat way to also prevent your DB class from being unset by accident.

I wrote the tutorial. You can find it here: http://www.phphelp.com/forum/index.php?topic=20456.msg70437#msg70437

Sponsor our Newsletter | Privacy Policy | Terms of Service