Search code examples
phpmysqlphp4

Yet another 'Call to a member function on a non-object' problem


I have a html page that calls a php object to get some data back from the database. It works fine, but the script was getting unwieldy so I decided to break some of it out into a bunch of functions.

So I have the following files:

// htdocs/map.php
<?php
    include("config.php");
    include("rmap.php");

    $id = 1;
    $gamenumber = getGameNumber($id);
    echo $gamenumber;
?>

// htdocs/config.php
<?php
$_PATHS["base"]      = dirname(dirname(__FILE__)) . "\\";
$_PATHS["includes"]  = $_PATHS["base"] . "includes\\";

ini_set("include_path", "$_PATHS[includes]");
ini_set("display_errors", "1");
error_reporting(E_ALL); 

include("prepend.php");
?> 

// includes/prepend.php
<?php
include("session.php");
?>

// includes/session.php
<?php
includes("database.php");

class Session {
    function Session() {
    }

};

$session = new Session;
?>

// includes/database.php
<?php
include("constants.php");

class Database {

    var $connection;

    function Database() {
        $this->connection = mysql_connect(DB_SERVER, DB_USER, DB_PASS) or die(mysql_error());
        mysql_select_db(DB_NAME, $this->connection) or die(mysql_error());
    }

    function query($query) {
        return mysql_query($query, $this->connection);
    }
};

/* Create database connection */
$database = new Database;
?>

// includes/rmap.php
<?php
function getGameNumber($id) {
    $query = "SELECT gamenumber FROM account_data WHERE usernum=$id";
    $result = $database->query($query); // line 5
    return mysql_result($result, 0);
}
?>

And constants has a bunch of defines in it (DB_USER, etc).

So, map.php includes config.php. That in turn includes prepend.php which includes session.php and that includes database.php. map.php also includes rmap.php which tries to use the database object.

The problem is I get a

Fatal error: Call to a member function on a non-object in C:\Develop\map\includes\rmap.php on line 5

The usual cause of this is that the $database object isn't created/initialised, but if I add code to show which gets called when (via echo "DB connection created"; and echo "using DB connection";) they are called (or at least displayed) in the correct order.

If I add include("database.php") to rmap.php I get errors about redefining the stuff in constants.php. If I use require_once I get the same errors as before.

What am I doing wrong here?


Solution

  • $database is not in the scope of function GetGameNumber.

    The easiest, though not necessarily best, solution is

    <?php
    function getGameNumber($id) {
        global $database;  // added this
        $query = "SELECT gamenumber FROM account_data WHERE usernum=$id";
        $result = $database->query($query); // line 5
        return mysql_result($result, 0);
    }
    ?>
    

    global is deemed not perfect because it violates the principles of OOP, and is said to have some impact on performance because a global variable and all its members are added to the function's scope. I don't know how much that really affects performance, though.

    If you want to get into the issue, I asked a question on how to organize such things a while back and got some good answers and links.