PHP Conference Japan 2024

$GLOBALS

(PHP 4, PHP 5, PHP 7, PHP 8)

$GLOBALS參考所有在全域範圍內可用的變數

說明

一個關聯式 陣列,包含目前在腳本全域範圍內定義的所有變數的參考。變數名稱是陣列的鍵值。

範例

範例 #1 $GLOBALS 範例

<?php

function test()
{
$foo = "local variable";

echo
'$foo in global scope: ' . $GLOBALS["foo"] . "\n";
echo
'$foo in current scope: ' . $foo . "\n";
}

$foo = "Example content";
test();

?>

上述範例的輸出會類似以下:

$foo in global scope: Example content
$foo in current scope: local variable

警告

從 PHP 8.1.0 開始,不再支援對整個 $GLOBALS 陣列的寫入操作。

範例 #2 寫入整個 $GLOBALS 將會導致錯誤。

<?php

// 會產生編譯時期錯誤:
$GLOBALS = [];
$GLOBALS += [];
$GLOBALS =& $x;
$x =& $GLOBALS;
unset(
$GLOBALS);
array_pop($GLOBALS);
// ...以及任何其他對 $GLOBALS 的寫入/讀寫操作

?>

注意事項

注意:

這是一個「超全域」或自動全域變數。這表示它在整個程式碼的所有作用域中都可用。在函式或方法中存取它不需要使用 global $variable;

注意變數可用性

與所有其他超全域變數不同,$GLOBALS 在 PHP 中基本上一直都是可用的。

注意:

從 PHP 8.1.0 開始,$GLOBALS 現在是全域符號表的唯讀副本。也就是說,無法透過其副本修改全域變數。先前,$GLOBALS 陣列不遵循 PHP 陣列通常的傳值行為,並且可以透過其副本修改全域變數。

<?php

// PHP 8.1.0 之前的版本
$a = 1;

$globals = $GLOBALS; // 表面上是按值複製
$globals['a'] = 2;
var_dump($a); // int(2)

// 從 PHP 8.1.0 開始
// 這不再修改 $a。先前的行為違反了按值語義。
$globals = $GLOBALS;
$globals['a'] = 1;

// 要恢復先前的行為,請迭代其副本並將每個屬性重新賦值給 $GLOBALS。
foreach ($globals as $key => $value) {
$GLOBALS[$key] = $value;
}

?>

新增註釋

使用者貢獻的註釋 4 則註釋

inafeeur at gmail dot com
2 年前
我們可以更清楚地說明給定範例的延伸。

PHP 8.1 之前的版本

<?php
$a
= 1;
$globals = $GLOBALS;
$globals['a'] = 2;
echo
$a; // 2
echo $globals['a']; // 2
echo $GLOBALS['a']; // 2
?>

PHP 8.1 之後的版本

<?php
$a
= 1;
$globals = $GLOBALS;
$globals['a'] = 2;
echo
$a; // 1
echo $globals['a']; // 2
echo $GLOBALS['a']; // 1
?>
therandshow at gmail dot com
13 年前
從 PHP 5.4 開始,$GLOBALS 現在是即時初始化的。這表示現在不使用 $GLOBALS 變數有一個優勢,因為您可以避免初始化它的開銷。我不確定這個優勢有多大,但我從來都不太喜歡 $GLOBALS。
mstraczkowski at gmail dot com
11 年前
當您嘗試將 $GLOBALS 設定為局部變數時要小心。

即使沒有參考運算子「&」,您的變數似乎也會被參考到 $GLOBALS

您可以使用以下程式碼測試此行為

<?php
/**
* 結果:
* POST: B, 變數: C
* GLOBALS: C, 變數: C
*/

// 測試 $_POST
$_POST['A'] = 'B';

$nonReferencedPostVar = $_POST;
$nonReferencedPostVar['A'] = 'C';

echo
'POST: '.$_POST['A'].', 變數: '.$nonReferencedPostVar['A']."\n\n";

// 測試 Globals
$GLOBALS['A'] = 'B';

$nonReferencedGlobalsVar = $GLOBALS;
$nonReferencedGlobalsVar['A'] = 'C';

echo
'GLOBALS: '.$GLOBALS['A'].', 變數: '.$nonReferencedGlobalsVar['A']."\n\n";
vittorio.zamparella at famous googlemail
8 年前
我終於找到關於在 $GLOBALS 中找不到超全域變數的資訊

https://bugs.php.net/bug.php?id=65223&edit=2
-------------------------------------
[2013-07-09 12:00 UTC] johannes @php.net
[...]基於效能考量,超全域變數(又稱自動全域變數)預設不會被加入到符號表中,除非解析器看到需要。例如:

<?php
$_SERVER
;
print_r($GLOBALS);
?>

將會列出它。您也可以使用 php.ini 中的 auto_gloals_jit 來控制它: https://php.dev.org.tw/manual/en/ini.core.php#ini.auto-globals-jit
-------------------------------------

https://php.dev.org.tw/manual/en/language.variables.variable.php
-------------------------------------
警告
請注意,在函式或類別方法中,無法將可變變數與 PHP 的超全域陣列一起使用。變數 $this 也是一個特殊的變數,無法動態地被參考。
-------------------------------------
To Top