I spoke briefly with Jan about the following (imho) mis-feature,
who recommended bringing it up on the dev-list.
http://bugs.php.net/?id=14952
I ran into the problem (as an end-user) while trying to muck
with what the user had passed in (ie: spoof GET data from
session-ized defaults if the user did not select anything).
Why isn't it: $_GET =& $HTTP_GET_VARS?
Attached is my understanding of the problem. As it stands
right now, I do not want to use $_GET constructs in my code
because $_GET is not a drop-in replacement for:
$GLOBALS['HTTP_GET_VARS'][...]
...which I assumed it was. No matter where I set a value for
$GLOBALS['HTTP_GET_VARS'], it will be the same throughout
script execution. With the addition of the $_GET class of
variables, there are suddenly two copies of data, two areas
to manage in your code. IMHO, it is a bad move for the data
to be separated in the long run, especially when there is not
a good reason for it.
If the world were a perfect place (which it isn't, and I know
it ;^) ... I would say that:
$_GET =& $GLOBALS['HTTP_GET_VARS'];
$_POST =& $GLOBALS['HTTP_POST_VARS'];
$_COOKIE =& $GLOBALS['HTTP_COOKIE_VARS'];
$_REQUEST =& array_merge( $_GET, $_POST, $_COOKIE );
I know that the last request (reference request to
the results of a function) isn't really possible or
feasible, but the first three definitely are.
Another possible solution would be to throw an E_WARNING
if $_GET or $GLOBALS['HTTP_GET_VARS'] is used as the left-
hand side of an expression. This would make changing
information within $_GET or $GLOBALS['HTTP_GET_VARS']
officially frowned upon, which would have alerted me to the
fact that now in 4.1.1 there are two places where a GET/POST
variable can be named and changed.
Or, if $_GET/$HTTP_GET_VARS is detected as a left-hand side
expression, call _internal_UPDATE_REQUEST( $key, $value ),
to keep all arrays in sync.
I wrote up some documentation about the $_* variables, which
I would appreciate it if someone more knowledgeable about the
inner workings of the $_GET stuff could look over it and let
me know if there are any mistakes. I release that
documentation to the PHP group under the same terms of license
as the rest of PHP's documentation, so please feel free to
integrate it if it is a welcome addition.
I am not subscribed to this list (am using it through the news
gateway now), so I might not receive any responses. I would
appreciate being CC'd any relevant discussion.
Thanks for everything so far, PHP rocks! :^)
--Robert (ramses0@yahoo.com / robert@sell.com)
Thank you for your response. I understand what the $_* arrays
are for, but I still disagree. :^)
echo $_GET['blah'];
echo $HTTP_GET_VARS['blah'];
$HTTP_GET_VARS['blah'] = 'test';
function test()
{
echo $_GET['blah'];
}
test();
Why is the array data separate? There is no good reason, and
several bad reasons.
Good reasons to be separate:
1) You might want $_GET and $H_G_V to be different
2) [some random reason about internal PHP code]
3) does $_REQUEST get updated if $_GET/$_POST is updated too?
Bad reasons to be separate:
1) takes twice as much memory
2) $_GET != $HTTP_GET_VARS after script execution begins
3) does $_REQUEST get updated if $_GET/$_POST is updated too?
At the very least, this is a documentation bug because $_GET !=
$HTTP_GET_VARS should be mentioned at
http://www.php.net/manual/en/language.variables.predefined.php
Here is my stab at documentation for $_* vars.
"""
With the introduction of PHP 4.1.1 there are several variables
introduced which are guaranteed to be available in every
function, no matter what the ini settings are. These variables
are: $_GET, $_POST, and $_COOKIE, and contain the same
information as their corresponding $HTTP_*_VARS arrays.
The other variable introduced is $_REQUEST, which is a merged
array of all GET/POST/COOKIE data.
SPECIAL NOTE: Although the information contained in $_GET,
$_POST, $_COOKIE, and $_REQUEST is initially the same as that
found in $HTTP_GET_VARS, $HTTP_POST_VARS, and $HTTP_COOKIE_VARS,
changes in one array do not impact changes in any other array.
It is considered a bug, hack, or workaround to *set* any value
in any of these arrays. (do not use them as a left-hand-side in
any expression). This will make your code more readable, more
maintainable, and more useful to other script authors.
Converting from older styles...
===============================
Assume that you have a script which takes a single parameter,
'blah'.
In global scope:
echo $blah; => echo $_REQUEST['blah'];
echo $GLOBALS['blah']; => echo $_REQUEST['blah'];
echo $HTTP_GET_VARS['blah'] => echo $_GET['blah'];
echo $GLOBALS['HTTP_GET_VARS']['blah'] => echo $_GET['blah'];
In function scope:
function demonstration()
{
global $blah, $HTTP_GET_VARS;
// 1: using global operator from above
echo $blah;
// 2: using array HTTP_GET_VARS from global scope
echo $HTTP_GET_VARS['blah'];
// 3: using no special functions
echo $GLOBALS['HTTP_GET_VARS']['blah'];
}
function demonstration()
{
// 1: no need to global the variable name
echo $_REQUEST['blah'];
// 1: also valid is:
global $blah;
echo $blah;
// 2: no need to global _GET, it is automatically available
echo $_GET['blah'];
// 3: same as #1, no need to change
echo $_REQUEST['blah'];
}
"""