PHP 迭代时的全局行为

PHP Global Comportement On Iteration

我目前正在试验一个奇怪的行为,同时在一个全局变量上迭代另一个全局变量取它的值

此代码

$lang_list = array('fr_FR', 'en_US');
$GLOBALS['lang_list'] = $lang_list;
if(isset($_GET['lang']) && in_array($_GET['lang'], $lang_list)){
    $GLOBALS['lang'] = $_GET['lang'];
}else{
    $GLOBALS['lang'] = 'en_US';
}

var_dump($GLOBALS['lang']);
foreach($GLOBALS['lang_list'] as $lang){
    var_dump($GLOBALS['lang']);
}

return string(5) "en_US" string(5) "fr_FR" string(5) "en_US"

是否由于与全局相关的原因而预期?

编辑: 谢谢大家的解释! :)

是的,这是预期的行为。 $GLOBALS['lang'] 引用全局范围内的 $lang 变量。 PHP中只有两个作用域:全局作用域和局部函数作用域(详见this answer)。

由于 foreach 循环不创建局部函数作用域,因此 $lang 变量属于全局作用域。因此,$lang$GLOBALS['lang'] 都引用同一个变量。

$GLOBALS['lang']$lang指的是同一个变量。来自 manual page for $GLOBALS:

An associative array containing references to all variables which are currently defined in the global scope of the script. The variable names are the keys of the array.

因此,当您在全局范围内更改 $lang 时,它也会更改 $GLOBALS['lang'](反之亦然,如果您更改 $GLOBALS['lang'],它也会更改 $lang)。因此,在您的 foreach 循环中,$GLOBALS['lang'] 依次从 $GLOBALS['lang_list'] 中分配值。

请注意,如果您 运行 在函数中使用此代码,您将获得预期的结果,因为在这种情况下 $lang 将在函数范围而不是全局范围中定义:

function test() {
    foreach($GLOBALS['lang_list'] as $lang){
        var_dump($GLOBALS['lang']);
    }
}

test();

输出:

string(5) "en_US"
string(5) "en_US"

Demo on 3v4l.org

请阅读 https://www.php.net/manual/en/reserved.variables.globals.php 手册。您在上面的代码中引用了相同的值。