Zend Framework 文檔強烈不建議使用 define 定義全局常量,推薦類常量 const。本文深度剖析 define 的三大核心問題:重複定義靜默失敗、判斷語法易錯、查找機制導致性能低,並給出類常量、類屬性、PHP_EOL 等最佳替代方案。
<?php
define('C', 12345);
define('C', 123); // Notice: Constant C already defined
// C 仍為 12345,第二次定義無效
?>
後果: 若他人先定義同名常量,你的代碼將使用錯誤值,且無異常拋出,極難排查。
<?php
define('C', 12345);
// ❌ 錯誤 1:isset 只能檢測變量
if (isset(C)) { ... } // Parse error
// ❌ 錯誤 2:defined 參數必須是字符串
if (defined(C)) { ... } // Notice: Use of undefined constant C
// ✅ 正確:字符串常量名
if (defined('C')) { ... }
?>
<?php
define('FORUM_THEME', $forum['theme']);
$this->display('/' . FORUM_THEME . '@Public:login');
// PHP 內部需在常量表中多次查找 FORUM_THEME,比變量慢
?>
常量存儲於 EG(zend_constants) 哈希表,每次使用需哈希查找;變量存儲於符號表,直接索引,速度更快。
<?php
class Config {
const WEBSITE = 'www.zhuyinghao.com';
protected $_forumTheme;
public function setForumTheme($theme) {
$this->_forumTheme = $theme;
}
public function display() {
echo self::WEBSITE; // 類內訪問
echo $this->_forumTheme; // 實例屬性
}
}
// 使用
echo Config::WEBSITE; // 類外訪問
$cfg = new Config();
$cfg->setForumTheme($forum['theme']);
$cfg->display();
?>
運行期才確定的值(如數據庫讀取的配置),用 protected $_xxx + getter/setter,避免 define 運行期定義的混亂。
__construct(),兼容舊式類名構造函數,但 __construct() 優先;__construct(),避免混淆。PHP_EOL\n;\r\n;\r;PHP_EOL 自動適配當前運行平台,寫日誌、生成文件必用。class const:命名空間隔離、編譯期綁定、IDE 自動提示;define 定義全局常量:污染全局命名空間、重複定義靜默失敗、判斷語法易錯、性能劣勢;PHP_EOL:跨平台兼容;__construct():現代 PHP 標準。貫徹「少用常量、用類封裝配置」原則,代碼更健壯、可維護性更強。