Forum Moderators: coopster
The problem I have with PHP global variables is that they work the opposite way as compared to other languages: they are declared in each function, instead of at file level.
I've spent hours debugging problems caused by omitting a variable from a "global" statement. I consider it a crime to have robbed me of my time like this.
And no, I can't make do by using $GLOBALS. That syntax is even worse, because it puts the syntactic burden on every reference to a global variable. The syntactic burden should only be in one place: at a single declaration of the global variable at file level.
Here is my solution: a way in PHP to declare global variables at file level and have them automatically be available inside functions, using a modicum of elegance.
Here is the usage:
// File level: declare global variable $MySQL
// (a MySQL connection resource)
G("MySQL");
// A typical function
function DoSQLQuery($Query)
{
eval(G); // Import all global variables
...
// Variable $MySQL can be referenced here
...
} // DoSQLQuery
If you want the global declaration to specify an initial value, do it like this:
G("MySQL",""); // Init to empty string
Here's all the code you need to implement this technique:
$GLOBALS["G_"]='$_';
define("G",'eval(eval(\'return \\\'global \\\'.$GLOBALS["G_"].\\\';\\\';\'));');
function G($VarName,$Init=NULL)
{
$GLOBALS["G_"].=",\$$VarName";
if (!is_null($Init))
$GLOBALS[$VarName]=$Init;
} // G
David Spector
[edited by: coopster at 9:49 pm (utc) on Oct. 3, 2006]
[edit reason] removed specifics TOS#13 [webmasterworld.com] [/edit]
You may notice that this is a little bit different from the C language in that global variables in C are automatically available to functions unless specifically overridden by a local definition. This can cause some problems in that people may inadvertently change a global variable. In PHP global variables must be declared global inside a function if they are going to be used in that function.emphasis added
Resource: [php.net...]
I guess if you are the developer you get to have it however you want ;)
Don't forget that $_GET, $_POST, etc. are in the global scope too. There would be an even easier way to get all globals available in your function:
function myFunction()
{
extract [php.net]($GLOBALS, EXTR_REFS);
$foo .= ' World!';
}
$foo = 'Hello';
print $foo; // Hello
myFunction();
print $foo; // Hello World
exit;
Be especially careful of importing all the values of the server arrays such as $_GET. A hacker can pass in a variable with the same name as one used in your program, and potentially create results you did not wish. Instead, you should import only the variables you used in your form. You can use code such as this, where you simply list your form variables in place of "Arg1,Arg2":
<?php
// This example PHP file is called by:
www.example.com/server.php?Arg1=123&Arg2=abc
// Get args from URL
$Args="Arg1,Arg2"; // Expected variable list
$Arg=strtok($Args,",");
while ($Arg)
{
$This=@$_GET[$Arg];
$$Arg=$This;
$Arg=strtok(",");
}
// At this point, $Arg1 is 123 and $Arg2 is "abc"
?>
In general, most variables should be local or passed as arguments. Where the use of global variables makes sense, they should be declared at the global (file) level. This is an accepted language design violated by PHP alone, so far as I know.
The extract function doesn't work, anyway. It imports copies of the variables (their values), not the variables themselves. If you set such a variable to a new value, the global variable of the same name is unchanged.
David Spector