Question

I have a problem with global variables in PHP. My problem is that a global variable that I change inside a static class method isn't updating outside the method.

I've included the code:

test.php

define( 'APP_ID', 'TESTING' );
$_APP = array( 'test' => 'test value' );
include ('appsettings.class.php');
AppSettings::initApplication();

appsettings.class.php

class AppSettings
{
  public static function initApplication()
  {
    global $_APP;
    session_start();

    // Some code here for your initializtions
    self::initAppEngine();
echo '<pre>Inside initApplication: '; print_r($_APP);
echo '<pre>Directly printing the session variable: '; print_r($_SESSION[APP_ID] );
  }

  private static function initAppEngine()
  {
    global $_APP;

    if( isset($_SESSION[APP_ID]) )
    {
      $_APP = &$_SESSION[APP_ID];
    }
    else
    {
      $_SESSION[APP_ID] = array( 'abcd' => 'hello', 'APP_ID' => APP_ID );
      $_APP = &$_SESSION[APP_ID];
die("Refresh the page");
    }

    if ( !isset( $_APP['uid'] ) )
      $_APP['uid'] = 0;

echo '<pre>Inside initAppEngine: '; print_r($_APP);
  }
}

The old value of $_APP is coming instead of the new one inside initApplication. Can anyone point out what I'm doing wrong?

Thanks in advance,

Was it helpful?

Solution

This is quite interesting. First of all, note that it seems to have nothing to do with static methods:

$_SESSION['test'] = array("test value from superglobal");
$_APP = array('test' => "test value directly assigned");

class AppSettings
{
  public static function initApplication()
  {
    global $_APP;
    $_APP = &$_SESSION['test'];
    echo '<pre>Inside initApplication: '; print_r($_APP);
  }

  public function initApplicationNonStatic()
  {
    global $_APP;
    $_APP = &$_SESSION['test'];
    echo '<pre>Inside initApplicationNonStatic: '; print_r($_APP);
  }
}

echo '<pre>Before calling initApplication: '; print_r($_APP);
AppSettings::initApplication();
echo '<pre>After calling initApplication: '; print_r($_APP);
echo '<pre>Before calling initApplicationNonStatic: '; print_r($_APP);
$appSettings = new AppSettings();
$appSettings->initApplicationNonStatic();
echo '<pre>After calling initApplicationNonStatic: '; print_r($_APP);

Result:

Before calling initApplication: Array
(
    [test] => test value directly assigned
)
Inside initApplication: Array
(
    [0] => test value from superglobal
)
After calling initApplication: Array
(
    [test] => test value directly assigned
)
Before calling initApplicationNonStatic: Array
(
    [test] => test value directly assigned
)
Inside initApplicationNonStatic: Array
(
    [0] => test value from superglobal
)
After calling initApplicationNonStatic: Array
(
    [test] => test value directly assigned
)

But this works:

$_SESSION['test'] = array("test value from superglobal");
$_APP = array('test' => "test value directly assigned");

class AppSettings2
{
  public function initApplicationNonStatic()
  {
    $GLOBALS['_APP'] = &$_SESSION['test']; // by reference
    echo '<pre>Inside initApplicationNonStatic: '; print_r($GLOBALS['_APP']);
  }
}

echo '<pre>Before calling initApplicationNonStatic: '; print_r($_APP);
$appSettings2 = new AppSettings2();
$appSettings2->initApplicationNonStatic();
echo '<pre>After calling initApplicationNonStatic: '; print_r($_APP);
$_SESSION['test'] = array("test value from superglobal altered");
echo '<pre>After altering superglobal: '; print_r($_APP);

Result:

Before calling initApplicationNonStatic: Array
(
    [test] => test value directly assigned
)
Inside initApplicationNonStatic: Array
(
    [0] => test value from superglobal
)
After calling initApplicationNonStatic: Array
(
    [0] => test value from superglobal
)
After altering superglobal: Array
(
    [0] => test value from superglobal altered
)

And this works, too:

$_SESSION['test'] = array("test value from superglobal");
$_APP = array('test' => "test value directly assigned");

class AppSettings2
{
  public function initApplicationNonStatic()
  {
    global $_APP;
    $_APP = $_SESSION['test']; // by value
    echo '<pre>Inside initApplicationNonStatic: '; print_r($_APP);
  }
}

echo '<pre>Before calling initApplicationNonStatic: '; print_r($_APP);
$appSettings2 = new AppSettings2();
$appSettings2->initApplicationNonStatic();
echo '<pre>After calling initApplicationNonStatic: '; print_r($_APP);
$_SESSION['test'] = array("test value from superglobal altered");
echo '<pre>After altering superglobal: '; print_r($_APP);

Result:

Before calling initApplicationNonStatic: Array
(
    [test] => test value directly assigned
)
Inside initApplicationNonStatic: Array
(
    [0] => test value from superglobal
)
After calling initApplicationNonStatic: Array
(
    [0] => test value from superglobal
)
After altering superglobal: Array
(
    [0] => test value from superglobal // expected, since assigned by value
)

So, it seems that whenever you want to assign a reference to a global variable inside a function or method, you have to use the $GLOBALS['_APP'] syntax and you cannot use global $_APP. If you don't need the assignment by reference, $GLOBALS['_APP'] and global $_APP behave the same.

I'm not exactly sure why this is so; some pages refer to the equivalence of these two constructs:

global $example;
$example =& $GLOBALS['example'];

This might lead to the right track; however, I hope that you can troubleshoot your problem with my answer.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top