Drew Galbraith
Drew Galbraith

Reputation: 2256

PHP class scope

I have several classes in an application that I am currently building, and I want to have one access some of the other's member functions but i can't seem to do it.

The first class is called MySQLDB:

class MySQLDB{
public $connection;

function __construct(){
//connects to database
}

function login($username, $password){
//queries database...
}
}

Then I have a class called Session:

class Session{
//variables
//constructor

function processlogin($username, $password){
$database->login($username, $password);
}

Then after this I have two class declarations:

$database = new MySQLDB();
$session = new Session();

No matter where i put these statements in relation to the classes I still get the same error:

PHP Notice:  Undefined variable: database in C:\inetpub\wwwroot\cmu\include\session.php on line 52
PHP Fatal error:  Call to a member function login() on a non-object in C:\inetpub\wwwroot\cmu\include\session.php on line 52

I have seen some suggestions that would suggest putting the new database object inside the Session class declaration but I want to avoid doing so because I use the database class several other places in the code and I don't want to open up multiple connections to the database.

Upvotes: 3

Views: 4223

Answers (4)

gion_13
gion_13

Reputation: 41533

you could pass a reference to the MySQLDB instance in the Session constructor.

class Session{
    public $db;

    function __construct(&$db=null){
        if($db == null)
            $this->db = new MySQLDB();
        else
            $this->db = $db;
    }
    // ....
}

$database = new MySQLDB();
$session = new Session($database);

Upvotes: 4

Sascha Galley
Sascha Galley

Reputation: 16091

since you want to have acces on a globally set variable, you can either gain access to it with global:

function processlogin($username, $password){
    global $database;
    $database->login($username, $password);
}

or use the variable as a parameter for the contructor and remember the database object reference in the class Session:

class Session{

    private $database;

    function __construct($database){
        $this->$database = $database;
    }

    function processlogin($username, $password){
        $this->database->login($username, $password);
    }

}

and then you call:

$database = new MySQLDB();
$session = new Session($database);

this comes in handy, if you use more functions afterwords, that also need access to the database object.

Upvotes: 4

Felix Kling
Felix Kling

Reputation: 816422

$database is not defined inside processlogin nor passed as parameter, hence the function has no access to it.

You could pass it as constructor parameter to Session:

class Session {
    private $db;

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

    public function processlogin($username, $password){
        $this->$db->login($username, $password);
    }
}

$database = new MySQLDB();
$session = new Session($database);

Upvotes: 2

Tomasz Kowalczyk
Tomasz Kowalczyk

Reputation: 10467

You are creating two global variables. If you're doing such thing, you need to declare variables you want to use in function with "global" keyword:

function processlogin($username, $password){
global $database;
$database->login($username, $password);
}

Despite this will work, I highly recommend reading about Dependecy Injection mechanism in which you'd pass $database variable as a parameter to processlogin() method, or set it as a private member of that class in constructor / setter. That way database connection will be interchangeable and you'll get more flexibility in your code.

Upvotes: 2

Related Questions