PHP 常數完整體系
PHP 提供多種常數定義方式,適用於不同層級:全域、類別、介面、命名空間。理解其差異能寫出更清晰、安全的程式碼。
一、全域常數:define()
<?php
// 基本定義(大小寫敏感)
define('APP_NAME', 'MySystem');
define('MAX_UPLOAD_SIZE', 10 * 1024 * 1024); // 10MB
// PHP 7.0+ 支援陣列常數
define('ALLOWED_EXT', ['jpg', 'png', 'gif', 'webp']);
// 大小寫不敏感(第三參數 true,PHP 7.3 棄用,8.0 移除)
define('DEBUG_MODE', true, true); // 不建議使用
// 使用方式:直接常數名,不加 $
echo APP_NAME;
$max = MAX_UPLOAD_SIZE;
if (in_array($ext, ALLOWED_EXT)) { ... }
- 執行時期定義,可動態決定值。
- 全域可見,不受命名空間限制(除非在命名空間中定義)。
- 不可重新定義,第二次呼叫會觸發 Notice 並忽略。
二、類常數:const
<?php
class Config {
// PHP 5.3+ 支援
const VERSION = '1.0.0';
const DEFAULT_LANG = 'zh_TW';
// PHP 5.6+ 支援運算式
const MAX_SIZE = 1024 * 1024 * 5; // 5MB
// PHP 7.1+ 可見度修飾詞
public const PUBLIC_KEY = 'pub';
protected const PROTECTED_KEY = 'prot';
private const PRIVATE_KEY = 'priv';
// PHP 8.0+ ::class 常數
public static function getClassName() {
return self::class; // 回傳 'Config'
}
}
// 存取方式
echo Config::VERSION;
echo Config::PUBLIC_KEY;
// $obj = new Config(); echo $obj::VERSION; // PHP 5.3+ 支援物件存取
三、介面常數
<?php
interface HttpStatus {
const OK = 200;
const NOT_FOUND = 404;
const SERVER_ERROR = 500;
}
echo HttpStatus::OK; // 200
四、魔術常數(預定義,依上下文動態變化)
| 常數 | 說明 | 範例輸出 |
| __LINE__ | 目前行號 | 15 |
| __FILE__ | 完整檔案路徑(已解析符號連結) | /var/www/html/index.php |
| __DIR__ | 檔案所在目錄(等同 dirname(__FILE__)) | /var/www/html |
| __FUNCTION__ | 函數名稱(區分大小寫) | myFunction |
| __CLASS__ | 類別名稱(含命名空間) | App\Controllers\UserController |
| __TRAIT__ | Trait 名稱 | App\Traits\Loggable |
| __METHOD__ | 類別方法名稱 | UserController::getProfile |
| __NAMESPACE__ | 目前命名空間名稱 | App\Controllers |
| ClassName::class | 類別完整名稱(PHP 5.5+) | App\Models\User |
五、命名空間下的常數
<?php
namespace App\Config;
define('App\Config\DB_HOST', 'localhost'); // 全域常數,建議加命名空間前綴
const API_KEY = 'secret'; // 屬於 App\Config 命名空間
// 使用
echo \App\Config\DB_HOST; // 全域
echo API_KEY; // 同命名空間
echo \App\Config\API_KEY; // 完整限定名
六、常數 vs 變數比較
| 特性 | 常數 | 變數 |
| 符號 | 無 $ | 有 $ |
| 修改 | 不可 | 可 |
| 作用域 | 全域/類別 | 依定義處 |
| 值型別 | 標量/陣列(PHP7+) | 任意 |
| 定義時機 | 編譯/執行期 | 執行期 |
最佳實踐建議
- 設定值、狀態碼、固定業務規則用常數,避免魔術數字散落程式碼。
- 類別內部常數用
const,全域應用層設定用 define() 或設定檔。
- 命名慣例:全域常數
UPPER_SNAKE_CASE,類常數 UPPER_SNAKE_CASE。
- 利用
::class 避免字串硬編碼類別名,支援 IDE 重構。
- 避免在迴圈或高頻路徑呼叫
define(),雖有快取但仍有開銷。