3

I was trying to get the name of a superglobal variable through a GET parameter. I was told to pass only _VAR_NAME (without the $) in the get request, so in the program I have to access it through a variable variable: $$_GET['parameter_name'].

Everything went fine except with $_SERVER. To try what was wrong I just did a small php script to test what was happening. Here is the code:

<?php
    // ¡¡ This does not work !!
        $nombre = "_SERVER";
        $var = $$nombre;
        print_r($var);
    // This works 
        $nombre = "_GET";
        $var = $$nombre;
        print_r($var);
?>

Is there any reason for the _SERVER version not working? I get the following error:

Notice: Undefined variable: _SERVER in ...

Czechnology
  • 14,832
  • 10
  • 62
  • 88
David Casillas
  • 1,801
  • 1
  • 29
  • 57

4 Answers4

2

When auto_globals_jit directive is enabled, the SERVER and ENV variables are created when they're first used (Just In Time) instead of when the script starts. PHP Manual warns about variable variables:

Usage of SERVER and ENV variables is checked during the compile time so using them through e.g. variable variables will not cause their initialization.

Possible solutions are:

  • Using the PHP function getenv() instead of the SERVER variable.
  • Adding just the line $_SERVER; before, or at the beginning of the script.
  • Disabled the directive (in php.ini: auto_globals_jit = Off, or inside the script: ini_set('auto_globals_jit',0);)
  • Using the key '_SERVER' in the array $GLOBALS ($GLOBALS['_SERVER'])
Leopoldo Sanczyk
  • 1,529
  • 1
  • 26
  • 28
2

I'm not sure why you need this, I don't use variable variables (there are usually better ways).

You could do a simple switch based on your $nombre variable, there are not so many superglobal variables!

switch ($nombre) {
  case "_SERVER" : 
    print_r($_SERVER);
    break;
  case "_GET" : 
    print_r($_GET);
    break;
  case "_POST" : 
    print_r($_POST);
    break;
  // ...
  default:
    echo "Unknown variable";
}
Czechnology
  • 14,832
  • 10
  • 62
  • 88
  • 1
    Ok, thanks for the aproach. But it's also important for me trying to undestand what's going wrong and learn the insides of php. Not just find a new workaround. – David Casillas Mar 09 '11 at 08:36
  • 1
    @David Casillas, I'm not sure what's wrong with the variable variables in your example. But if you want to get better in php, using variable variables is not the way. The code gets harder to read and debug and is sometimes prone to security risk. Just because php has this feauture doesn't mean it's good. But that's just my humble opinion, use what works for you ;) – Czechnology Mar 09 '11 at 08:55
1

You can try the alternative syntax:

$var = $GLOBALS["_SERVER"];
print_r($var);

This is functionally equivalent to $$varvar.

One more critical thing to check is if $_SERVER itself is there. (If not, place an empty count($_SERVER); expression at the start of your script.)

It can be absent if variables_order= was modified in the php.ini (though it should really just show up as empty array in recent PHP versions.)

mario
  • 144,265
  • 20
  • 237
  • 291
  • Why does adding any direct reference to $_SERVER (`count($_SERVER`) for example) makes the code start working OK? – David Casillas Mar 09 '11 at 08:29
  • @DavidCasillas: Note sure, but I've read the superglobals are sometimes initialized on first access (depends on the SAPI). -- But I think the actual problem in your case might be that you tried `$$SERVER` in a local scope. The superglobals (`$_SERVER`) are not really superglobal, but only implicitly global. The `$$varvar` does not reference the real `$_SERVER`, but only a local array if it hasn't been explicitly accessed before. **In short: the `$$SERVER` varvar only works in the global scope.** Anyway, use `$GLOBALS[_serv]` to be safe. – mario Mar 09 '11 at 12:09
0

It Works perfectly here for me. have you tried print_r ($_SERVER)

it might not be populated on your system.

make sure you have not unset it somewhere in your script.


Are you using it in a function or class?

The warning states that this cannot be used on superglobals within functions or classes.

Your best bet is the switch statement.

frostymarvelous
  • 2,786
  • 32
  • 43
  • I have just added your line of code at the end of the script, and that made the code work. I also tried Mario's trick adding count($_SERVER) and it also works. So it seems that the variable is unset. I have not unset it myself, and don't understand this subject. What may be happening? – David Casillas Mar 08 '11 at 17:48
  • It's not inside any function or class. I have tried in another server and it works, so seems that has something to do with the server configuration. – David Casillas Mar 08 '11 at 18:00
  • Ah okay server specific then. Goodluck. I advise you to try the switch for superglobals and set the default case to use variable variables for other variables. – frostymarvelous Mar 08 '11 at 18:20