PHP 中定義常量與靜態成員的三種方式——define()、const、static——在作用域、解析時機、內存模型、類成員訪問等方面存在本質差異。本文從底層原理到工程實踐全維度解析。
| 特性 | define() | const | static |
|---|---|---|---|
| 定義位置 | 全局/函數內/條件分支 | 類內/頂層作用域 | 類內成員/函數內局部 |
| 解析時機 | 運行時 | 編譯時 | 運行時(首次訪問) |
| 值類型限制 | 任意表達式 | 標量/常量表達式(PHP 5.6+) | 任意表達式 |
| 大小寫敏感 | 可配置(第三參數) | 永遠敏感 | 變量名敏感 |
| 命名空間 | 全局/當前命名空間 | 受命名空間約束 | 類作用域 |
| 內存分配 | 預處理替換,無獨立內存 | 編譯期分配,有類型檢查 | 類加載時分配,實例共享 |
| 訪問方式 | 常量名直接訪問 | 類名::常量名 / self::常量名 | self::$var / 類名::$var |
| 可變性 | 不可變(運行時定義後) | 不可變 | 可變(運行時修改) |
define('PI', 3.14) 與 define('PI', '3.14') 效果相同
// 條件定義(const 不支持)
if (extension_loaded('redis')) {
define('CACHE_DRIVER', 'redis');
} else {
define('CACHE_DRIVER', 'file');
}
// 表達式作為值
define('MAX_SIZE', 1024 * 1024 * 100); // 100MB
// 動態常量名
for ($i = 0; $i < 32; $i++) {
define('BIT_' . $i, 1 << $i);
}
// 大小寫不敏感
define('APP_DEBUG', true, true);
echo APP_DEBUG; // true
echo app_debug; // true
const B = A + 1)ClassName::CONST
class Config {
// 類常量
const VERSION = '2.0';
const MAX_RETRY = 3;
// PHP 5.6+ 常量表達式
const DEFAULT_LIMIT = 10;
const PAGINATION = self::DEFAULT_LIMIT * 2; // 20
// 錯誤示例
// const DYNAMIC = time(); // 編譯錯誤:非常量表達式
// if (true) { const X = 1; } // 語法錯誤:不能在條件分支中定義
}
// 訪問
echo Config::VERSION; // 2.0
echo Config::PAGINATION; // 20
public/protected/private 修飾static::$var 實現靜態綁定
class Counter {
private static $count = 0; // 靜態屬性
const VERSION = '1.0'; // 類常量
public function __construct() {
self::$count++; // 必須用 self:: 或 static::
}
public function __destruct() {
self::$count--;
}
public static function getCount() {
return self::$count;
}
// 靜態方法只能訪問靜態成員
// $this->count 會報錯
}
// 使用
$c1 = new Counter();
$c2 = new Counter();
echo Counter::getCount(); // 2
echo Counter::VERSION; // 1.0
// 測試代碼
define('D_CONST', 'value');
const C_CONST = 'value';
$start = microtime(true);
for ($i = 0; $i < 1000000; $i++) { $x = D_CONST; }
echo "define: " . (microtime(true) - $start) . "s\n";
$start = microtime(true);
for ($i = 0; $i < 1000000; $i++) { $x = C_CONST; }
echo "const: " . (microtime(true) - $start) . "s\n";
// 典型輸出
// define: 0.045s
// const: 0.032s // 約快 30%
原因:const 編譯期直接內聯到 opcode,define 運行時需查找常量表。
const MAX_RETRY = 3)const APP_ENV = 'prod')static::$var 晚綁定)const ARR = [1,2,3],5.6 以下報錯class A { define('X', 1); } 定義的是全局常量,非類常量const STR = "val{$var}" 不支持,需用 define理解三者本質差異,能編寫更健壯、高性能、可維護的 PHP 代碼。