PHP 全域變數在類別、函式、檔案引入等不同場景下的行為差異,是開發者常遇到的困惑點。本文透過五個具體場景,深度解析全域變數與類別結合的運作機制。
<?php
// father.php
$jack = 1000;
?>
<?php
// children.php
require("father.php");
$jack = 123;
echo $jack . "\n"; // 輸出 123
?>
解析: PHP 解析執行順序為由上而下。require 引入時執行 father.php 設定 $jack=1000,隨後 children.php 覆蓋為 123。若註解掉 $jack=123 則輸出 1000;若將賦值置於 require 之前則被覆蓋,輸出 1000。
<?php
require("father.php");
function testJack() {
if (!isset($jack)) {
echo '$jack is null' . "\n";
}
}
testJack(); // 輸出: $jack is null
?>
函式內部預設為區域作用域,$jack 被視為區域變數 (未定義)。
<?php
require("father.php");
function testJack() {
global $jack; // 宣告使用全域變數
if (!isset($jack)) {
echo '$jack is null' . "\n";
} else {
echo '$jack is not null' . "\n";
}
}
testJack(); // 輸出: $jack is not null
?>
<?php
require("father.php");
class JackTest {
public function testJack() {
global $jack; // 類別方法同樣需宣告
if (!isset($jack)) {
echo '$jack is null' . "\n";
} else {
echo '$jack is not null' . "\n";
}
}
}
$jackTest = new JackTest();
$jackTest->testJack(); // 輸出: $jack is not null
?>
關鍵點: 類別方法內部同樣遵循函式作用域規則,需以 global $jack 宣告才能存取全域變數。
<?php
$casefile = $_SERVER['argv'][1]; // 取得命令列參數
echo $casefile . "\n";
require($casefile); // 動態引入
echo $jack . "\n";
?>
執行 php children.php father.php 可動態載入指定檔案並存取其定義的全域變數。
目錄結構:
c.php |- Bfold/b.php |- Afold/a.class.php (內部 require "../Bfold/b.php")
在 c.php 中 new Aclass(),a.class.php 內部 require("../Bfold/b.php") 報錯。
PHP 解析路徑相對於主執行檔案 (c.php),而非當前被引入檔案。解決方法:將路徑改為相對 c.php 的 require("Bfold/b.php")。
<?php
// C.php
function caller() {
require("B.php"); // 函式內引入
}
caller();
?>
<?php
// B.php (一般敘述區)
require_once("A.php"); // 相當於呼叫匿名函式執行 A.php
?>
<?php
// A.php
$globalVar = "test";
?>
global 或直接變數名存取global $var 或 $GLOBALS['var']require_once 載入定義全域變數的檔案,易造成作用域混淆