常數是執行期間不可變更的值(除魔術常數外)。本文完整整理 PHP 常數的定義規則、內建常數、魔術常數與實務應用建議。
一、常數基礎
命名規則
- 區分大小寫(慣例全大寫)
- 合法命名:
[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*
- 不以
$ 開頭
- 全域作用域,無視命名空間限制
定義方式
<?php
// define() 函式(執行時期定義)
define('APP_NAME', 'My Application');
define('MAX_UPLOAD_SIZE', 10 * 1024 * 1024); // 運算式需 PHP 5.6+
// const 關鍵字(編譯期定義,類別常數必須用 const)
const API_VERSION = 'v1';
// 動態名稱定義
$const_name = 'DB_' . strtoupper($env) . '_HOST';
define($const_name, 'localhost');
// 檢查是否定義
if (defined('APP_NAME')) {
echo APP_NAME;
}
// 取得所有已定義常數
print_r(get_defined_constants(true)['user']); // 只看使用者定義
?>
常數 vs 變數
| 特性 | 常數 | 變數 |
| 前綴 | 無 | $ |
| 定義方式 | define() / const | 指派運算子 |
| 作用域 | 全域 | 依定義處決定 |
| 可重新定義 | 不可 | 可 |
| 可取消定義 | 不可 | unset() 可移除 |
| 資料型別 | 純量 | 任意型別 |
二、魔術常數(依使用位置動態變化)
| 常數 | 說明 | 範例輸出 | 可用版本 |
__LINE__ | 目前行號 | 42 | 所有版本 |
__FILE__ | 完整路徑與檔名(已解析符號連結) | /var/www/html/index.php | 所有版本 |
__DIR__ | 檔案所在目錄(等同 dirname(__FILE__)) | /var/www/html | PHP 5.3+ |
__FUNCTION__ | 函式名稱(區分大小寫) | myFunction | PHP 4.3+ |
__CLASS__ | 類別名稱(含命名空間,區分大小寫) | App\Models\User | PHP 4.3+ |
__TRAIT__ | Trait 名稱(含命名空間) | App\Traits\Loggable | PHP 5.4+ |
__METHOD__ | 類別方法名稱 | App\Models\User::getName | PHP 5.0+ |
__NAMESPACE__ | 目前命名空間名稱 | App\Models | PHP 5.3+ |
魔術常數實務範例
<?php
namespace App\Services;
class Logger {
public function log($message) {
$prefix = "[".date('Y-m-d H:i:s')."] ";
$prefix .= __CLASS__ . "::" . __FUNCTION__ . " (".__FILE__.":".__LINE__.") ";
error_log($prefix . $message . "\n", 3, __DIR__ . '/../storage/logs/app.log');
}
}
?>
三、核心預定義常數
PHP 版本資訊
| 常數 | 說明 |
PHP_VERSION | 版本字串(如 "8.2.10") |
PHP_VERSION_ID | 版本號整數(如 80210,方便版本比較) |
PHP_MAJOR_VERSION | 主版本號 |
PHP_MINOR_VERSION | 次版本號 |
PHP_RELEASE_VERSION | 釋出版本號 |
PHP_EXTRA_VERSION | 額外版本標識(如 -dev, -RC1) |
PHP_ZTS | 是否啟用 Thread Safety (1/0) |
PHP_DEBUG | 是否為 Debug 版本 |
作業系統與路徑
| 常數 | 說明 |
PHP_OS | 作業系統名稱(Linux, WINNT, Darwin...) |
PHP_OS_FAMILY | OS 系列(Linux, Windows, BSD, Darwin...,PHP 7.2+) |
DIRECTORY_SEPARATOR | 目錄分隔符(/ 或 \) |
PATH_SEPARATOR | 路徑分隔符(: 或 ;) |
錯誤報表層級
E_ERROR, E_WARNING, E_PARSE, E_NOTICE, E_DEPRECATED, E_STRICT, E_ALL
布林與空值
true, false, null
四、命名空間與常數
<?php
namespace App\Config;
const API_KEY = 'xxx'; // 完整名稱:App\Config\API_KEY
// 存取方式
echo API_KEY; // 相對存取
echo \App\Config\API_KEY; // 絕對存取
echo namespace\API_KEY; // 相對存取(明確)
// 導入常數 (PHP 5.6+)
use const App\Config\API_KEY;
use const App\Config\DB_HOST as HOST;
echo API_KEY;
echo HOST;
?>
五、常見陷阱與最佳實踐
陷阱 1:未定義常數被視為字串
<?php
echo UNDEFINED_CONST; // 輸出 "UNDEFINED_CONST" 並發出 E_NOTICE
// 正確寫法
defined('UNDEFINED_CONST') && UNDEFINED_CONST;
?>
陷阱 2:const 只能定義純量(PHP 5.6+ 可定義陣列)
<?php
// PHP 5.6+
const ALLOWED_EXT = ['jpg', 'png', 'gif'];
define('ALLOWED_EXT', ['jpg', 'png', 'gif']); // PHP 7.0+ 支援陣列
?>
最佳實踐清單
- 設定值用常數:資料庫連線、API 金鑰、路徑、業務規則常數
- 類別常數用 const:
class Config { const MAX_RETRY = 3; }
- 全域常數用 define():啟動檔、設定檔集中定義
- 避免魔術數字:
if ($status === 1) → if ($status === Order::STATUS_PAID)
- 命名加前綴:
APP_、DB_、CACHE_ 避免衝突
- 善用 PHP_VERSION_ID 版本判斷:
if (PHP_VERSION_ID >= 80000) { ... }
常數是程式碼可讀性與維護性的基石,善用內建常數與自訂常數,能大幅減少硬編碼帶來的風險。