Log in

View Full Version : PHP Global Object



jscheuer1
07-05-2010, 09:26 PM
Is there a name for the global object in PHP?

Like in javascript, if you are outside of all functions, all five of these are equivalent (though the last four are less prone to lead to errors later):


bark = 'woof';

var bark = 'woof';

window.bark = 'woof';

self.bark = 'woof';

this.bark = 'woof';

The last three of these all use javascript's obj.propertyName convention, and in this case this, window, and self all refer to the global object (at least in a browser environment).

Is there one or more keyword(s) that do this in PHP. I know it cannot be window, because there is no window on the server. And this appears in limited testing to be meaningless in PHP's global scope.

I know there must be a PHP global object. Otherwise:


$myVar = 'bob';

and really all PHP code wouldn't do anything. But it's possible that there is no name/keyword for the global object PHP.

Anyone know for sure on this one?

traq
07-05-2010, 10:12 PM
see my example below. this post was confusing.

no, there isn't really such a keyword. basically, everything is in the global scope unless it's in some other scope :D

$this only works from within a class (object).

so, whatever scope you're in when you assign a variable is the scope it's available in. AFAIK, you can't assign a variable to a particular scope while you're inside another. In the global scope (outside all functions, classes, namespaces), $myVar = 'bob'; creates a global variable. Inside a function/class/namespace, it creates a local variable. If you're inside a function and you want to reference a variable in the global scope, you can use $GLOBALS['myVar'] (references $myVar) or declare global $myVar; (from inside the local scope; makes $myVar available in the current, local scope).

kinda counter-intuitive, IMHO... I would have made it so you could create a variable in the global scope, declare it global, and then have it automatically available in all scopes... but oh well. it is what it is. that's basically what $GLOBALS does, I guess.

jscheuer1
07-05-2010, 10:49 PM
Can you give me an example of using a variable defined outside a function in a function without passing it to the function?

Or can you give me an example of defining a global variable inside a function and then later accessing it outside that function?

Are there any of either?

Your post tends to imply that there are (perhaps only one or the other), but doesn't show any clear way in which to do either one.

traq
07-05-2010, 11:07 PM
hmm...

<?php

$myVar = 'global scope';

function using_GLOBALS(){
$myVar = 'local scope';
echo $myVar; // outputs 'local scope'
echo $GLOBALS['myVar']; // outputs 'global scope'
}

// OR

function using_global(){
echo $myVar; // outputs nothing
global $myVar;
echo $myVar; // outputs 'global scope'
}

?>as far as defining a global variable from inside a local scope, I'm not sure it can be done. the best thing I can think of is:
<?php

function return_global(){
$var = 'value';
return $var;
}

$myVar = return_global();

?>

better explanation than mine: variable scope (http://php.net/manual/en/language.variables.scope.php)



equally ugly, but this works too, and it saves the return for more important stuff:
<?php

function make_global(){
$mylocalvar = 'I was born local';
$GLOBALS['myVar'] = $mylocalvar;
}

make_global();
echo $GLOBALS['myVar'];

// you could, obviously, use $_SESSION, $_ENV, whatever, instead.
// but, despite the fact that it works,
// I don't think any of the superglobals were actually intended for this use -
// so it might cause unforeseen problems.

?>As far as I can tell, all the "global" methods seem aimed at bringing global things into the local scope, and not vice-versa.
The confusing thing (for me, at least) is that global things aren't available locally - not by default.

djr33
07-06-2010, 12:13 AM
traq has answered everything in detail.

Here's a summary and a couple more things:

"global $var;" anywhere will force a variable to be global.
"$var;" is irrelevant and you should just skip to using the variable. If you must preset a variable to avoid referring to an empty variable, then give it a value, such as FALSE, 0 or ''. Frequently $ar = array(); is helpful to avoid looping through possibly empty arrays.

$GLOBALS['var'] is something I recently discovered and I love it. This allows clarity while using the variable rather than sometimes sharing globals and other times not.

Objects are just variables and work like any other.
$obj = new Obj;
Then you use it like anything else.
$obj->var refers to a variable inside the object (similar to an array, but complex).
$this->var refers to that same variable, but only within the class (and subclass??).

Aside from those, I'm not aware of anything similar to the javascript "."/dot method. In PHP, there's -> for classes and of course arrays where you can get $var['one']['two'], so somtimes that can kinda be similar to your window.var example, but not in that sense.

The main difference in PHP and JS is that you never need to declare a variable to use it (I'm not even sure if you should/can). Just declare a variable as global if needed, or I'd now recommend using $GLOBALS.


One last thing: there are a few special "superglobals" that never change scope. Thus you can always call $_GET, and other vars with the underscore anywhere. (Unfortunately you can't make up your own like $_MYVARS.)

traq
07-06-2010, 12:36 AM
"global $var;" anywhere will force a variable to be global.

Do you mean like this?
<?php

$myVar = 'global';
global $myVar;

function use_global(){
echo $myVar;
}

use_global();

?>That was my initial interpretation of the global keyword, but it does not work.
global actually means "I'm looking for this variable in the global scope".

jscheuer1
07-06-2010, 01:03 AM
From playing with this a bit, I think:


"global $var;" anywhere will force a variable to be global.

Should read:

global $var; anywhere will force a variable to have its global value in that scope.

But I may still not have gotten it.

Thanks for your functions traq, I've tried them and they really show at least some (perhaps all) of what can be done in this regard.

It appears though that one can't create a variable in a function and have it be available unadorned in the global scope, rather (notwithstanding using the function's return, which is really creating the variable in the global scope in the normal way) it must be created as a property of an existing global object and addressed as such in whatever scope it is later accessed from. Like (not so eloquent as your examples):


$GLOBALS['someVar'] = 'bob';

function echoBob(){
echo $GLOBALS['someVar'];
}

echoBob(); // outputs bob

traq
07-06-2010, 01:04 AM
actually, Daniel, that reminds me: constants.

You can make a value available *anywhere* in your script by defining it as a "constant":
<?php

define('MY_VAR', 'I am constant as the northern star');

echo MY_VAR; // works

function local_scope(){
echo MY_VAR; // also works
}

?>However, constants can only be scalar values (e.g., integer, float, string, boolean - arrays, objects, functions, expressions, etc. don't work).
<?php

define('MY_VAR', 'constant'); // scalar; works
define('MY_VAR2', MY_VAR.' 2'); // two scalars; also works
define('MY_VAR', 1+2); // expression; doesn't work
define('MY_VAR', my_function()); // doesn't work, even if the function returns a scalar value

// etc.

?>

traq
07-06-2010, 01:10 AM
global $var; anywhere will force a variable to have its global value in that scope.

yes.



$GLOBALS['someVar'] = 'bob';

function echoBob(){
echo $GLOBALS['someVar'];
}

echoBob(); // outputs bob oh my...

that gave me an idea.. it works locally (xampp); I'm gonna try it live in a minute. this:
<?php

function make_global(){
$GLOBALS['someVar'] = 'bob';
}

make_global();
echo $someVar; // outputs 'bob'

?>totally works. exports to the global scope. awesome!

jscheuer1
07-06-2010, 01:28 AM
That looks like the missing link.

djr33
07-06-2010, 01:28 AM
Correct in your replies: global $var; tells the function to collapse the local and global values into the global variable.
There is no way to create a "superglobal" as in $_GET that will then be ALWAYS global. But using global or $GLOBALS[] will allow you to access them as needed.

Unless you're doing a lot with the value, my favorite method is this:

function myfunc() {
$myvar = $GLOBALS['myvar'];
echo $myvar; //or something else...
}


Globals can get complicated, but the simple rule I use is this: if you need to use a global value, declare global $var; as the first line inside your function (or possibly within a conditional if needed). Alternatively use $GLOBALS and there will be no confusion (hopefully), and at the very least no ambiguity.

What I don't know about the 'global' keyword is what happens when you do this at a weird time:

$myvar = 1;
function myfunc() {
$myvar = 2;
global $myvar;
echo $myvar; //2? 1?
}
myfunc();
echo $myvar; //2? 1?

I haven't tested this (never really needed to), but this is a possible place of much confusion so just make sure you set everything global you need at the start or use $GLOBALS, and you'll be fine.

I'm planning to rewrite everything on my current project, when I get to it, to use $GLOBALS instead of 'global'.


Now, if you want to play with something more confusing, the & operator in PHP is very complex. This is used in function calls.

$var = 1;
function func(&$v) {
$v = 2;
}
func($var);
echo $var; //2!!
And it can do other things. Declaring "&" at runtime generates a deprecated warning, though. (Ex: calling myfunc(&$var);, rather than having that as a default in the function definition).


traq, regarding constants:
I hate constants. I wish they were redefinable. I guess this would change their nature entirely, but they're very near useless except to store never-variable information. And at that, it's much more likely that you'll not even care what's in them, but that they are set at all.
The only exception I make to this is that they're great for a security system: on your primary page (index?) establish:
define('MYSITE',1);
Then in any other pages, to make sure this is being accessed properly:
if (!is_defined('MYSITE')) { exit; }
And that's it. This allows you to ignore scope and just deal with this simple value. You could also do more things like set that the user has passed the login, etc., but that gets too variable (no pun intended), and constants are no longer very helpful.

traq
07-06-2010, 02:56 AM
What I don't know about the 'global' keyword is what happens when you do this at a weird time:

$myvar = 1;
function myfunc() {
$myvar = 2;
global $myvar;
echo $myvar; //2? 1?
}
myfunc();
echo $myvar; //2? 1?I got '1' both times. not what I expected, though. :)

Now, if you want to play with something more confusing, the & operator in PHP is very complex. This is used in function calls.

$var = 1;
function func(&$v) {
$v = 2;
}
func($var);
echo $var; //2!!geez, I hate that stupid thing. however, your example seems to allow you to set a global variable from a local scope, so that's good to know.


traq, regarding constants:
...
they're great for a security system: on your primary page (index?) establish:
define('MYSITE',1);
Then in any other pages, to make sure this is being accessed properly:
if (!is_defined('MYSITE')) { exit; }
absolutely. I love that. I take it a step further:
<?php

if (!is_defined('MYSITE')) { header("Location: http://www.mysite.com/index.php"); exit; }

?>One thing I do find constants useful for is defining site-wide chunks of "whatever" that may need to be used in several, or varying, places. Such as:
<?php

define('DESIGNER', 'Web design by <a href="http://www.custom-anything.com/">Adrian</a>');

// blahblahblah...

$footer = 'Site &copy; 2010 by a Client. &nbsp;'.DESIGNER;
echo $footer;

?>

djr33
07-06-2010, 03:00 AM
Constants are fine but not flexible. If you have some reason these might vary or do something odd in any case, they won't work. In general, probably one third of our variables could be replaced by constants, but without any real reason except that we don't change the values.
However, if you're using that sort of code in a few places it's not a bad idea. It does get around the scope easily.
And I agree that for security the method is good, but I've found constants otherwise frustratingly limited. A header is fine, though where I'm using this I hope no one tries to go there, since it's never meant to be public (or even viewed by me). Of course for a login or something it would be different.


Interesting about "1" being the return value. I'd think the exact opposite. But this means then that "global $var;" is basically just an alias for "$var = &$GLOBALS['var'];"

Note: the & in this case apparently links the two variables to act as one: one is the alias of the other, tied together unless you do something else. Unsetting the alias just removes that, not the variable, though.

In fact, it's practically this function:

function global(&$var) {
$var = &$GLOBALS[$var];
}

And there's the annoying "&". In this case there's no other way to access that local variable.
Note that & allows us not only globals but also higher local variables... interesting.
(I can't ever remember a time I have used &, except when modifying someone else's script...)

That just reached the extent of my knowledge about &, and I'm not even sure it's used correctly there, but that's close enough for an example I guess.

traq
07-06-2010, 03:48 AM
Interesting about "1" being the return value. I'd think the exact opposite. But this means then that "global $var;" is basically just an alias for "$var = &$GLOBALS['var'];"
yeah.

my understanding of global is that it does the same thing as $GLOBALS, but is persistent (you can use $var directly instead of typing out $GLOBALS['var'] every time).

I read (somewhere) about the & creating a "reference" to the content of another variable - allowing both variables to point at (and therefore, work with) the same content. Something like having several shortcuts pointing at the same file (or, probably more like several filenames pointing at the same data). Each reference has full access to the content. Of course, I wonder what would happen if:corrected experiment code
<?php

$myVar = 1; // global

function local(&$v){
$v = 2; // local
more_local($v);
echo 'local: '.$v;
}

function more_local(&$v){
$v = $v+1;
echo 'more local: '.$v;
}

local($myVar);
echo 'global: '.$myVar;

?>

any predictions? :D

djr33
07-06-2010, 04:14 PM
It should change it's value each time and finally be global with the new value.

traq
07-06-2010, 08:04 PM
yeah, all three echoes take place after the more_local function does its modification, so the output is "3" each time. That experiment wasn't as confusing/interesting as I thought it would be... oh well. :p

jscheuer1
07-07-2010, 12:16 AM
I Still liked it. 3 3 3

Anyways, though in itself virtually useless, I think this is interesting:


<?php
$someVar = 'bob';
echo $GLOBALS['someVar'] . '<br>'; // outputs bob<br>

function changeVar(&$var, $val){
$var = $val;
}

changeVar($someVar, 'ted');

echo $someVar; // outputs ted
?>

traq
07-07-2010, 12:56 AM
I think we're all nerds.

jscheuer1
07-07-2010, 03:25 AM
Nerds are cool now, didja know?