2013-07-22 6 views
3

У меня проблема с глобальными переменными в PHP. Моя проблема в том, что глобальная переменная, которую я изменяю внутри метода статического класса, не обновляется вне метода.Глобальная переменная, не обновляющаяся внутри статического метода класса в PHP

Я включил код:

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); 
    } 
} 

Старое значение $ _APP приходит вместо нового внутри initApplication. Может ли кто-нибудь указать, что я делаю неправильно?

Заранее спасибо,

ответ

3

Это довольно интересно. Прежде всего, отметим, что, кажется, не имеют ничего общего со статическими методами:

$_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); 

Результат:

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 
) 

Но это работает:

$_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); 

Результат:

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 
) 

И это тоже работает:

$_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); 

Результат:

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 
) 

Таким образом, кажется, что всякий раз, когда вы хотите назначить ссылку к глобальной переменной внутри функции или метода, вы должны использовать синтаксис $GLOBALS['_APP'] и вы не можете использование global $_APP. Если вам не требуется назначение по ссылке, $GLOBALS['_APP'] и global $_APP ведут себя одинаково.

Я не совсем уверен, почему это так; somepages относится к эквивалентности этих двух конструкций:

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

Это может привести к правильному пути; однако я надеюсь, что вы сможете устранить проблему с моим ответом.

+0

Удивительный ответ, спасибо! Я пытался использовать $ _GLOBALS, но я не уверен, почему это не сработало, когда я попробовал. Моя единственная проблема прямо сейчас с вышеупомянутой техникой заключается в том, что мне нужно, чтобы $ _APP работал и внутри моих других функций (хотя мне не понадобится назначение по ссылке). Я собираюсь проверить, работает ли он так, как я хочу. В любом случае, спасибо за отличный ответ! – GarbageGigo

+0

Не очень знакомы с ответом на StackOverflow, извините за несколько комментариев. Как вы думаете, я должен подать отчет об ошибке, потому что нам не нужно использовать $ _GLOBALS? А также, спасибо за ссылки (очень полезно понять ссылки). – GarbageGigo

+0

Мне кажется, вам нужно определенное количество репутации, чтобы отредактировать свои комментарии. :-) Пожалуйста, используйте '$ GLOBALS' вместо' $ _GLOBALS' (но я думаю, это опечатка).Что касается подачи ошибки, я не уверен, я думаю, что это поведение может быть предназначено или, скорее, эффект реализации самого PHP, тем более, что вы должны думать, что в прошлом больше людей приходило в голову. Возможно, это имеет смысл, хотя я не могу понять, почему пока. Возможно, вы можете связаться с кем-то из команды разработчиков PHP без подачи ошибки сразу? Не уверен, что лучший подход. – stef77

Смежные вопросы