在PHP 開發中,常量常用於配置參數、狀態值等不希望在程序執行過程中被更改的數據。自PHP 5.3 起,命名空間的引入極大地提升了代碼組織與模塊化能力。但一個實際問題也隨之而來:當我們想獲取某個特定命名空間下定義的所有常量時,PHP 本身並未直接提供針對命名空間篩選常量的函數。這時候, get_defined_constants()就成為一個值得深入研究的工具。
get_defined_constants()函數會返回一個關聯數組,其中包含當前腳本中所有已定義的常量。通過傳入布爾值true參數,還可以按照分類(包括用戶自定義常量)進行分組:
$constants = get_defined_constants(true);
print_r($constants['user']); // 獲取所有用戶自定義常量
這可以幫我們初步過濾掉PHP 核心常量、擴展常量等無關內容,但這還不足以按命名空間細分。
命名空間下定義的常量,實質上在PHP 內部是作為全局常量存在的,只不過其名稱中包含了命名空間前綴。例如:
namespace App\Config;
const TIMEOUT = 30;
這個常量在get_defined_constants()返回結果中的鍵名會是App\Config\TIMEOUT 。因此,我們可以通過正則匹配或字符串前綴判斷的方式,從返回結果中篩選出我們感興趣的常量。
以下是一個簡單的函數,它用於從用戶自定義常量中篩選出屬於特定命名空間的部分:
function get_namespace_constants(string $namespace): array {
$allConstants = get_defined_constants(true);
$userConstants = $allConstants['user'] ?? [];
$namespacePrefix = trim($namespace, '\\') . '\\';
$filteredConstants = [];
foreach ($userConstants as $name => $value) {
if (strpos($name, $namespacePrefix) === 0) {
$filteredConstants[$name] = $value;
}
}
return $filteredConstants;
}
調用示例:
print_r(get_namespace_constants('App\\Config'));
該函數會返回類似以下結構的數組:
Array
(
[App\Config\TIMEOUT] => 30
[App\Config\RETRIES] => 5
)
常量必須先定義
get_defined_constants()只能獲取到在調用前已被定義的常量。這意味著你必須確保對應的文件(或命名空間)已加載。
命名規範<br> 若多個命名空間下有重複常量名,篩選時依賴的是全名(包括命名空間),不會產生衝突
可封裝為工具函數或類方法<br> 如果你經常需要獲取某模塊或命名空間下的常量,不妨將上述邏輯封裝到通用工具類中,提高代碼復用性
在某些框架或自定義框架中,常量可作為配置項的替代或補充方式。可以結合get_namespace_constants()實現配置的自動註冊。例如:
$config = get_namespace_constants('App\\Config');
file_put_contents('https://m66.net/log/config_snapshot.json', json_encode($config));
通過這種方式,可以將配置快照保存或發送到遠程系統,便於運維或故障排查。
雖然PHP 沒有直接提供按命名空間列出常量的原生函數,但我們依然可以通過get_defined_constants()搭配命名空間前綴規則,實現這一需求。掌握這類技巧不僅能提高代碼組織能力,也能在框架開發或大型系統中發揮實際價值。