p2p.wrox.com Forums

Need to download code?

View our list of code downloads.


  Return to Index  

beginning_php thread: 4.1.0 Globals


Message #1 by "Gerry Vandermaesen" <gerry.v@s...> on Tue, 17 Sep 2002 16:36:13 +0200
If I would want to use the 4.1.0 globals like $_GET and $_POST in a
4.0.x version of PHP, would it be a good idea to include a file in all
my PHP files with the following code, or are there better solutions?
 
<?php
global $_SERVER, $_ENV, $_COOKIE, $_GET, $_POST, $_FILES, $_REQUEST,
$_SESSION;
while (list($key,$val) = each($HTTP_SERVER_VARS)) {
    $_SERVER[$key] = $val;
}
while (list($key,$val) = each($HTTP_ENV_VARS)) {
    $_ENV[$key] = $val;
}
while (list($key,$val) = each($HTTP_COOKIE_VARS)) {
    $_COOKIE[$key] = $val;
}
while (list($key,$val) = each($HTTP_GET_VARS)) {
    $_GET[$key] = $val;
}
while (list($key,$val) = each($HTTP_POST_VARS)) {
    $_POST[$key] = $val;
}
while (list($key,$val) = each($HTTP_FILES_VARS)) {
    $_FILES[$key] = $val;
}
while (list($key,$val) = each($HTTP_REQUEST_VARS)) {
    $_REQUEST[$key] = $val;
}
while (list($key,$val) = each($HTTP_SESSION_VARS)) {
    $_SESSION[$key] = $val;
}
?>


Message #2 by "Nikolai Devereaux" <yomama@u...> on Tue, 17 Sep 2002 09:41:46 -0700
This would be easier:

$superglobals = array('GET', 'POST', 'COOKIE',
                      'FILES', 'ENV', 'REQUEST',
                      'SESSION', 'SERVER');

foreach($superglobals as $sg)
{
   $GLOBALS[$sg] = & ${'HTTP_' . $sg . '_VARS};
}


See, in your solution, you copy all the values, one at a time, from each of
the arrays, into a new one.

In the way I show above, I create a global reference to the original array.
That way, changes in the new global $_GET directly modify the $HTTP_GET_VARS
array.

Keep in mind that this isn't a be-all-end-all solution!  your $_XXX
variables are _NOT_ superglobals, which means you'll still have to import
them into global scope with "global $_GET;" or the like.


My suggestion is to simply upgrade PHP to the latest version.  There's no
real reason NOT to, unless you're perhaps using an older version of an
experimental extension who's functions have changed.  (The XSLT extension
was changed between early PHP4 and now.)  That wasn't so much of an
obstacle, and considering the security benefits to having the most recent
and patched version, deliberately running an old version of PHP makes little
sense.

If it's out of your hands, that's another matter -- in that case, I'd harp
your ISP or sysadmin to upgrade PHP!

Nik

Message #3 by "Gerry Vandermaesen" <gerry.v@s...> on Tue, 17 Sep 2002 19:39:52 +0200
Well indeed it's out of my hand, as my provider is sticking to 4.0.3 for
the moment. I guess they will upgrade sooner or later, but in the
meantime I would like to start using the new superglobal notation
anyway.

Thanks for the input anyway. I just got soms remarks/questions:

I guess the foreach loop won't work for $_FILES, as the older notation
is $HTTP_POST_FILES (my mistake in the first mail).
Ofcourse the $_REQUEST variable was only introduced in 4.1.0, came to
that conclusion after visiting the php.net pages juster after sending my
email.
And finally, do I really need to put them explicitely in the global
scope afterwards as you are already creating references in the
superglobal $GLOBALS? Doesn't that make them global anyway?

Regards,

Gerry.

-----Original Message-----
From: Nikolai Devereaux [mailto:yomama@u...] 
Sent: dinsdag 17 september 2002 18:42
To: beginning php
Subject: [beginning_php] RE: 4.1.0 Globals



This would be easier:

$superglobals = array('GET', 'POST', 'COOKIE',
                      'FILES', 'ENV', 'REQUEST',
                      'SESSION', 'SERVER');

foreach($superglobals as $sg)
{
   $GLOBALS[$sg] = & ${'HTTP_' . $sg . '_VARS};
}


See, in your solution, you copy all the values, one at a time, from each
of the arrays, into a new one.

In the way I show above, I create a global reference to the original
array. That way, changes in the new global $_GET directly modify the
$HTTP_GET_VARS array.

Keep in mind that this isn't a be-all-end-all solution!  your $_XXX
variables are _NOT_ superglobals, which means you'll still have to
import them into global scope with "global $_GET;" or the like.


My suggestion is to simply upgrade PHP to the latest version.  There's
no real reason NOT to, unless you're perhaps using an older version of
an experimental extension who's functions have changed.  (The XSLT
extension was changed between early PHP4 and now.)  That wasn't so much
of an obstacle, and considering the security benefits to having the most
recent and patched version, deliberately running an old version of PHP
makes little sense.

If it's out of your hands, that's another matter -- in that case, I'd
harp your ISP or sysadmin to upgrade PHP!

Nik



Message #4 by "Nikolai Devereaux" <yomama@u...> on Tue, 17 Sep 2002 11:03:36 -0700
Okay, my mistake!  I've been using the $_xxx vars for such a long time now
that I'm getting rusty about pre 4.1.0 varnames. =)

> I guess the foreach loop won't work for $_FILES, as the older notation
> is $HTTP_POST_FILES (my mistake in the first mail).
> Ofcourse the $_REQUEST variable was only introduced in 4.1.0, came to
> that conclusion after visiting the php.net pages juster after sending my
> email.

$_REQUEST is kind of a lame array, imho.  I mentioned why in another email I
posted this morning:
  http://p2p.wrox.com/view.asp?list=beginning_php&id=214936

You can still use the foreach for the "normal" variables, and modify the
rest like so:

$superglobals = array('GET', 'POST', 'COOKIE',
                      'ENV', 'SESSION', 'SERVER');

foreach($superglobals as $sg)
{
  $oldname = 'HTTP_' . $sg . '_VARS';

  if(isset($$oldname))
  {
    $GLOBALS['_' . $sg] = & $$oldname;
  }
}

if(isset($HTTP_POST_FILES))
{
  $GLOBALS['_FILES'] = & $HTTP_POST_FILES;
}


> And finally, do I really need to put them explicitely in the global
> scope afterwards as you are already creating references in the
> superglobal $GLOBALS? Doesn't that make them global anyway?

Well, yes and no.  I've created global variables which are references to
other arrays.  In a function, you still have to import them into that
functions scope with the global keyword.

In other words, you have $_GET and $_POST and all those defined as global
variables.  That they are references to other arrays is unimportant -- the
key is that they are _NOT_ superglobal variables in and of themselves.

Any function you write that uses these new variables would have to import
them, like this:

function do_something($some_param)
{
   global $_POST, $_GET;
   ...
}


whereas in PHP 4.1.0 and newer, you don't.


The reason I put them explicitly in global scope ($GLOBALS['_' . $sg]) is
because I didn't know if you were going to copy and paste that code inside
some function somewhere.  Let's say you WERE in a function -- the code I
posted above would just create local variables which are references to the
global HTTP_xxx_VARS arrays.

In fact, now that I look at it, the snippet of code I posted wouldn't really
do all that much inside function scope, because HTTP_xxx_VARS were not
explicitly imported from global scope.  This would be more robust:


$superglobals = array('GET', 'POST', 'COOKIE',
                      'ENV', 'SESSION', 'SERVER');

foreach($superglobals as $sg)
{
  $oldname = 'HTTP_' . $sg . '_VARS';

  if(isset($GLOBALS[$oldname]))
  {
    $GLOBALS['_' . $sg] = & $GLOBALS[$oldname];
  }
}

if(isset($GLOBALS['HTTP_POST_FILES']))
{
  $GLOBALS['_FILES'] = & $GLOBALS['HTTP_POST_FILES'];
}


And if you want to set $_REQUEST, you can do so with array_merge().  Since
that function was introduced with php 4.0.6, I don't think you have it.
Here's a replacement:

function array_merge()
{
   $argc = func_num_args();
   $ret = array();
   for($i = 0; $i < argc; ++$i)
   {
      $arr = func_get_arg($i)
      foreach($arr as $key => $val)
      {
         $ret[$key] = $val;
      }
   }

   return $ret;
}


$GLOBALS['_REQUEST'] = array_merge($GLOBALS['_GET'],
                                   $GLOBALS['_POST'],
                                   $GLOBALS['_COOKIE'],
                                   ...
                                  );

Be sure to pass the arguments to array merge in the order that you want them
inserted.  IN the above example, _COOKIE['foo'] would overwrite _GET['foo'],
if they were both set.


hth,

nik


  Return to Index