Page 1 of 2

$GLOBAL, global, and scope theory question.

Posted: Wed Jan 10, 2007 5:05 pm
by thowden
Hi All

I've read and re-read everything on scope, variables, globals, and superglobals and I still cannot quite wrap my head around it.

I am maintaining some code written by others and they include in this application the use of $GLOBAL(variable) with the obvious intention that this would make the data available throughout the scripts. But it wasn't. I'll try to explain.

The 'script' consists of a number of files. The page file which includes_once a header, menu, functions, and finally footer file along with some display code. That part is pretty standard stuff (at least I think it is). There is then the function file which in turn includes some class files i.e. class.client.php & class.manager.php. The function file willl instantiate a new manager and in turn the class manager can instantiate a new client, (seems convoluted, but in the main it works). (Remember that I am doing maintenance not rewriting in full)

Throughout the various files there is use of $GLOBAL['client'][$variable] without any global $variable statements.

The problem that I was facing was that the $GLOBAL['client'][variable] would lose its value as the script transferred between its file components. The original scripts make the assumption that setting $GLOBAL['client'][variable] = 'value' at any point in the script means it will be available anywhere else in the script, which is clearly not the case, but I don't know why. I have now solved this actual issue by inserting some return values from some functions and forcing the $GLOBAL['client'][variable] = $result.

My question(s) is not to solve the problem but to help me understand 'why is it so?'

What is the relationship between global and $GLOBAL?
Does $GLOBAL rely on a variable being initially declared by the global $variable; statement ?
Does $GLOBAL become a new instance if invoked from within a new instance of a class?
Is there a limit or a change of scope in cascading include statements?

Thanks in advance.

Tony

Posted: Wed Jan 10, 2007 5:38 pm
by jyhm

Posted: Wed Jan 10, 2007 5:40 pm
by volka
thowden wrote:What is the relationship between global and $GLOBAL?
They use the same/identical internal structure to store data.
thowden wrote:Does $GLOBAL rely on a variable being initially declared by the global $variable; statement ?
No.
thowden wrote:Does $GLOBAL become a new instance if invoked from within a new instance of a class?
Is there a limit or a change of scope in cascading include statements?
No, as long the php instance is the same $GLOBALS is the same.
But e.g. with include('http://serv.er/script.php') script.php is handled by another php instance (and usually the http:// is simply gratuitous or even wrong)

What does

Code: Select all

<?php
echo 'phpversion: ', phpversion(), "<br />\n";
echo 'php_sapi_name: ', php_sapi_name(), "<br />\n";
echo 'php_uname: ', php_uname('s'), "<br />\n";
print?

Posted: Wed Jan 10, 2007 6:55 pm
by thowden
Hi

Thanks. Yes I have read this section several times. I understand the concept of scope within a function and a single file or script. My questions are more on scope limits where there are multiple script files and class instances. This doesn't seem to be mentioned in any docs I have read.

cheers
Tony

Posted: Wed Jan 10, 2007 7:08 pm
by volka
Script files are no scope boundaries. Multiple instances of a class running in the same php instance share the same global scope and the same array $GLOBALS
The output of my little script would still be nice to have.

Posted: Wed Jan 10, 2007 7:29 pm
by thowden
Hi
volka wrote:
thowden wrote:What is the relationship between global and $GLOBAL?
They use the same/identical internal structure to store data.
They use the same structure but

Code: Select all

echo 'Test<br />';
global $variable;
$GLOBAL['variable'] = 'test';
$variable = 'fred';

echo '$variable is set to : '.$variable.' <br />';
echo '$GLOBAL[\'variable\'] is set to : '.$GLOBAL['variable'].' <br />';
echo '$GLOBAL[variable] is set to : '.$GLOBAL[variable].' <br />';
echo '$GLOBAL[$variable] is set to : '.$GLOBAL[$variable].' <br />';

results in:
Test
$variable is set to : fred 
$GLOBAL['variable'] is set to : test 
$GLOBAL[variable] is set to : test 
$GLOBAL[$variable] is set to :
Which tells me that $GLOBAL[variable] is different to global $variable; so while they use the same struture you cannot use $GLOBAL to access a value set with global which is in part what these scripts were trying to do?
volka wrote:
thowden wrote:Does $GLOBAL rely on a variable being initially declared by the global $variable; statement ?
No.
So declaring $GLOBAL[$variable] = 'fred' and elsewhere in a script $test = $GLOBAL[$variable]; should result in $test = 'fred' ?
volka wrote:
thowden wrote:Does $GLOBAL become a new instance if invoked from within a new instance of a class?
Is there a limit or a change of scope in cascading include statements?
No, as long the php instance is the same $GLOBALS is the same.
But e.g. with include('http://serv.er/script.php') script.php is handled by another php instance (and usually the http:// is simply gratuitous or even wrong)
These scripts do not use a full URL but do traverse directories on the same server to the includes. i.e. nothing that would indicate that we have left or changed the PHP scope which I assume to be related to a specific browser session. So for my workstation using xBrowser the top-most scope is the PHP scope and this is the level at which the $GLOBAL superglobal exists?

In which case if $GLOBAL[variable] is set to a value within a function why is it not holding that value when called from a different function within the same script (set of included .php files)?
volka wrote:What does

Code: Select all

<?php
echo 'phpversion: ', phpversion(), "<br />\n";
echo 'php_sapi_name: ', php_sapi_name(), "<br />\n";
echo 'php_uname: ', php_uname('s'), "<br />\n";
print?

Code: Select all

phpversion: 4.4.0
php_sapi_name: apache2filter
php_uname: Linux
Thanks

Tony

Posted: Wed Jan 10, 2007 7:39 pm
by thowden
volka wrote:Script files are no scope boundaries. Multiple instances of a class running in the same php instance share the same global scope and the same array $GLOBALS
The output of my little script would still be nice to have.
I was drafting the last reply while you were posting. Output done.

I am assuming that the php instance you refer to terminates at the end of the script, generally as the server provides the ouput response to the client and that the scope of that script and the $GLOBALS array would also be dumped at that point?

From http://us2.php.net/manual/en/reserved.v ... es.globals: "An associative array containing references to all variables which are currently defined in the global scope of the script. The variable names are the keys of the array. "

This is the sentence that doesn't appear consistent with my testing (see previous post).

Tony

Posted: Wed Jan 10, 2007 7:55 pm
by Christopher
The global keyword is very different from the $GLOBALS superglobal variable. First, there are normal and superglobal variables. Normal vars are visible only within their scope -- so either in the global scope or in the function in which they are defined. Superglobals are visible everywhere regardless of scope. The global keyword is used to bring a variable outside the current scope into the current scope's namespace. Here is some code:

Code: Select all

<?php
// this is the global scope
$myvar = 'hello';

function test($var3) {

// if you want to access $myvar you can either bring it into the current scope with global
     global $myvar;
     echo "global myvar = $myvar<br/>";

// or you can access $myvar using $GLOBALS
     echo "GLOBALS['myvar'] = {$GLOBALS['myvar']}<br/>";

}

Posted: Wed Jan 10, 2007 8:35 pm
by thowden
Hi

Thanks. *Slaps forehead* Doh!@ $GLOBAL[variable] is NOT $GLOBALS[variable] See what happens when you leave an S out ! Hence none of my little tests worked before.

So global $variable; as a statement is not putting the $variable but getting the $variable ? Thanks 'arborint' for the clue in your sample, which I extended here just to confirm the options:

Code: Select all

<?php
    function testwith() { 
        // if you want to access $myvar you can either bring it into the current scope with global 
         global $variable; 
         echo "global variable = $variable<br/>"; 
    }
    function testwithout($variable) { 
        // or you can pass it explicitly 
         echo "passed variable = $variable<br/>"; 
    }
    function testglobals() { 
        // or you can access $myvar using $GLOBALS 
         echo "GLOBALS['variable'] = {$GLOBALS['variable']}<br/>"; 
    }
    // this is the global scope 
    $variable = 'fred'; 
    echo 'test function results<br />';
    echo testwith();
    echo testwithout($variable);
    echo testglobals();

Results in :

Test
test function results
global variable = fred
passed variable = fred
GLOBALS['variable'] = fred
Ok. So this brings me back to the original query (before I was side-tracked by my attack of mis-spellink) which is that if I have
$GLOBALS['client'][$variable] = 'fred' in a function within a script why is it disappearing or not available ($GLOBALS['client'][$variable] is empty or null) in another function? There must be something else impacting on the variables and I would guess that it will be related to having access to the variable values as either $GLOBALS[variables] or $variables.

Thanks for the feedback so far, I'll do a bit more research.

Tony

Posted: Wed Jan 10, 2007 8:49 pm
by volka
Maybe it's unset somewhere

Code: Select all

function xyz() {
	unset($GLOBALS['var']);
}

$var = 'abc';
echo 'var: ', $var, " \n";
echo '$GLOBALS[var]: ', $GLOBALS['var'], " \n";
xyz();
echo isset($var) ? 'set': 'not set', " \n";
echo isset($GLOBALS['var']) ? 'set': 'not set', " \n";
prints
var: abc
$GLOBALS[var]: abc
not set
not set

Posted: Thu Jan 11, 2007 1:50 am
by dibyendrah

Code: Select all

<?php
$x = "Z";

function test(){
	$x = "Y";
	print "Local x is ". $x."\n";
	
	global $x;
	print "Global x is ".$x."\n";
	
	$GLOBALS['x'] = "X";
	print "Super Global x is now ".$GLOBALS['x'];
}

test();

?>
Output :

Code: Select all

Local x is Y
Global x is Z
Super Global x is now X

Posted: Thu Jan 11, 2007 2:17 am
by RobertGonzalez
Where and when in the script is it set? As long as the script is processing forward the last set value should stay in place.

Posted: Thu Jan 11, 2007 3:57 am
by dibyendrah
After testing in different modes, I'm confused now :?:

Code: Select all

<?php
$x = "Z";

function test(){
	$x = "Y";
	print "Local x is ". $x."\n";

	unset($x);

	global $x;
	print "Global x is ".$x."\n";

	global $x;
	$x = "X";

	unset($x);

	print "Super Global x is now ".$GLOBALS['x'];
}

test();

?>
[/syntax]

Code: Select all

Local x is Y
Global x is Z
Super Global x is now X

Again,


Code: Select all

<?php
$x = "Z";

function test(){
	$x = "Y";
	print "Local x is ". $x."\n";

	unset($x);

	global $x;
	print "Global x is ".$x."\n";

	global $x;
	$x = "X";
	
	unset($x);

	print "Super Global x is now ".$x;
}

test();

?>

Output is

Code: Select all

Local x is Y
Global x is Z
Super Global x is now
That means, for every variables there are another copy of global variables. Is that so ?

Posted: Thu Jan 11, 2007 8:10 am
by volka
http://de3.php.net/unset wrote: The behavior of unset() inside of a function can vary depending on what type of variable you are attempting to destroy.

If a globalized variable is unset() inside of a function, only the local variable is destroyed. The variable in the calling environment will retain the same value as before unset() was called.
btw:
print "Super Global x is now ".$x;
where's the superglobal? ;)

Posted: Fri Jan 12, 2007 7:37 am
by dibyendrah
Oh! I'm sorry Volka! I meant global not super global. :D