Jump to content

Global doesn't work properly in PHP 5


Debbie-Leigh

Recommended Posts

Hi,

 

My websites have just been moved to a new server with PHP 5 on it and it seems the the global statement has changed it's behaviour slightly.

 

I have a set of functions which control the session reading and writing. They've been working fine on php 4 for several years now, but in PHP 5 they seem to be having a problem globalising the database object at the end of processing.

 

After much testing, I discovered that if I globalise the object in the last function to be executed (i.e. the one with the exit statement), then there is no problem.  This seems rather odd to me, as I thought that the whole point of the global statement is that you can globalise variables from anywhere. I wouldn't have thought that you should have to globalise them all the way back up the call tree, just to be able to use them in the function at the bottom of the tree. So, I'm a little confused and would like some advice.

 

My functions are:

funEnd {
do some stuff;
exit();
}

the session function:

function funSessRead($strKey) {
// Read a session from the database

global $dbSite;

$qsSession = $dbSite->runQuery("SELECT value FROM " . TBLSITE_SESSION . " WHERE session_id = '" . $strKey . "' AND expiry > '" . time() . "'");
if  ($qsSession):
	$rsSession = $dbSite->fetchArray();
	return $rsSession["value"];
else:
	return "";
endif;
}

 

In this setup, $dbSite->runQuery produces the error: "Fatal error: Call to a member function runQuery() on a non-object". The only way I've found to make it work is to globalise $dbSite in funEnd as well, like this:

funEnd {
global $dbSite;
do some stuff;
exit();
}

 

Does anyone know whether this is just a bug in PHP5 and whether there is a way to stop the new behaviour?

 

Debbie

 

Link to comment
Share on other sites

They can be a security issue, but the main problem is they clutter the global namespace and make debugging harder. Functions in particular are made to isolate pieces of functionality. Its always better to have functions accept variables from outside via parameters. This makes your functions more reusable, makes understanding where variables are defined clearer and prevents variables being overridden accidentally.

Link to comment
Share on other sites

Hi,

 

I do understand your theory, but there are occasions (this one in particular) where you can't pass the required variable(s) to the function.

 

The problem is that using global doesn't seem to work anymore in my example, without globalising it in the function that calls exit(). The database object seems to have been lost by the time the session tidy up happens, but in PHP4, the object still existed, so the session function could still use the existing database connection.

 

Which makes me think that PHP5 has had it's object clean up routine moved to happen earlier, perhaps before the session clean up happens.

 

Can you or anyone confirm whether this is the case?

 

Debbie

 

Link to comment
Share on other sites

For the last few years, pre v5, I've used

 

$cnx = odbc_connect(params);

function foo()
{
    global $cnx;
    // some odbc query requiring $cnx
}

function bar()
{
    global $cnx;
    // other odbc query requiring $cnx
}
?>

 

i.e. each function using $cnx declares it as global. No change just because it's v5

 

edit: note to the purists: this is one of the rare occasions I use global, where it's set once and never changed

Link to comment
Share on other sites

Hi,

 

FYI, for anyone with a similar problem. Rather than spending any more time trying to pinpoint what was looking to be one of those really obscure problems, I solved this problem by creating another link to the database within the session function, so it doesn't need to rely on the previously declared database object being available.

 

So my function now looks like:

function funSessRead($strKey) {
// Read a session from the database

@require(INC_CONFIG_DB_SITE);

$qsSession = $dbSite->runQuery("SELECT value FROM " . TBLSITE_SESSION . " WHERE session_id = '" . $strKey . "' AND expiry > '" . time() . "'");
if  ($qsSession):
	$rsSession = $dbSite->fetchArray();
	return $rsSession["value"];
else:
	return "";
endif;
}

The require calls in the script that sets up a database connection and assigns it to $dbSite which will be isolated within this function, so it won't affect anything outside that uses the other $dbSite object.

 

Debbie

 

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.