-1

Possible Duplicate:
Reference - What does this error mean in PHP?

I have two classes:

  1. Database Class
  2. Libtables Class

In the Database Class I've created an object to work with mysqli for the entire script. It works when I'm trying to call a function from the Database Class in a .php file.

Simplified Database Class:

class Database {

protected static $_instance;
protected $_mysqli;
protected $_query;


public function __construct($host, $username, $password, $db) {
    $this->_mysqli = new mysqli($host, $username, $password, $db)
        or die("There was a problem connecting to the database");
}

public function close() {

    $this->_mysqli->close();

}

public function query($q) {
    return $this->_mysqli->query($q);
}

}

But when I'm trying to call a function from the Database Class in the Libtables Class it fails and I get an error called: "Call to a member function query() on a non-object"

Simplified Libtables Class:

class Libtables {

    function getCol($table) {
    $q = "SELECT * from " . $table . ";";
    $res = $db->query($q);
    return $res;
    }

}

I've created a Database Class Object this way:

$db = new Database(DB_HOST, DB_USER, DB_PASS, DB_NAME);
global $db;
Community
  • 1
  • 1
Angelo A
  • 2,744
  • 6
  • 28
  • 37
  • 2
    Have you read the documentation about [global](http://php.net/manual/en/language.variables.scope.php)? – zerkms Oct 21 '12 at 13:26

3 Answers3

3

You need global $db; in your getCol function.

function getCol($table) {
    global $db;
    $q = "SELECT * from " . $table . ";";
    $res = $db->query($q);
    return $res;
}

Edit based on comment below.

Another option is to store the DB as a property in the class. The following a a simplified response. (You should look at making the var $db private and passing in through a constructor. See the documentation on variable scope and object constructors for more details.)

class Libtables {

    var $db;

    function getCol($table) {
        $q = "SELECT * from " . $table . ";";
        $res = $this->db->query($q);
        return $res;
    }

}

$oLibtables = new libtables();
$oLibtables->db = $db;
Robbie
  • 17,605
  • 4
  • 35
  • 72
  • But if I have 100 functions in that class, do I need to add global $db; to every function? – Angelo A Oct 21 '12 at 13:29
  • Yes - if you do it that way. Another way is to store the DB connection as a property of the class, and reference $this->db->query() – Robbie Oct 21 '12 at 13:30
  • @Angelo A: exactly. That's why `global` is evil. You need to pass it to the `Libtables` constructor and store it as a class property – zerkms Oct 21 '12 at 13:30
  • Isn't that what I did with the protected variable $_mysqli ? – Angelo A Oct 21 '12 at 13:32
  • The protected variable is in the database class, not in libtables. You could possible make libtables extend database - but I don't think that's what you want to do. – Robbie Oct 21 '12 at 13:35
1

The issue you are experiencing has to do with scope. The $db variable is not initialized within the Libtables class.

You can go about this either by defining the $db variable global in the function you need to use it i.e.

class Libtables 
{
    public function getCol($table) 
    {
        global $db;

        $q = "SELECT * from " . $table . ";";
        $res = $db->query($q);

        return $res;
    }
}

Or you could inject the variable through the class constructor so that you can use it everywhere (a bit cleaner code than using globals).

class Libtables 
{
    private $_db;

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

    public function getCol($table) 
    {
        $q = "SELECT * from " . $table . ";";
        $res = $this->_db->query($q);

        return $res;
    }
}

Creating Libtables

$db = new Database(DB_HOST, DB_USER, DB_PASS, DB_NAME);
.....
$lib = new Libtables($db);

HTH

Nikolaos Dimopoulos
  • 11,495
  • 6
  • 39
  • 67
0

Thanks everybody. It works now with passing the Database object through to the libtables Class.

Angelo A
  • 2,744
  • 6
  • 28
  • 37