PHP Conference Japan 2024

常數

目錄

常數是一個簡單值的識別符號(名稱)。顧名思義,該值在腳本執行期間不能更改(魔術常數除外,它們實際上並不是常數)。常數區分大小寫。按照慣例,常數識別符號始終使用大寫。

注意:

在 PHP 8.0.0 之前,使用 define() 函式定義的常數可能不區分大小寫。

常數的名稱遵循與 PHP 中任何標籤相同的規則。有效的常數名稱以字母或底線開頭,後跟任意數量的字母、數字或底線。作為正規表示式,它可以表示為: ^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$

可以使用保留名稱甚至無效名稱 define() 常數,其值只能使用 constant() 函式擷取。但是,不建議這樣做。

提示

另請參閱 使用者端命名指南

範例 #1 有效和無效的常數名稱

<?php

// 有效的常數名稱
define("FOO", "something");
define("FOO2", "something else");
define("FOO_BAR", "something more");

// 無效的常數名稱
define("2FOO", "something");

// 這是有效的,但應避免:
// PHP 未來可能會提供一個魔術常數
// 這會導致您的腳本失效
define("__FOO__", "something");

?>

注意在此,字母指的是 a-z、A-Z 以及 ASCII 字元 128 到 255 (0x80-0xff)。

如同 超全域變數,常數的作用域是全域的。常數可以在腳本中的任何位置存取,而無需考慮作用域。有關作用域的更多資訊,請閱讀手冊中關於 變數作用域 的章節。

注意從 PHP 7.1.0 開始,類別常數可以宣告 protected 或 private 的可見性,使其僅在定義它的類別的階層作用域中可用。

新增註解

使用者貢獻的註解 9 則註解

wbcarts at juno dot com
12 年前
2016/11/14 - 註解由 sobak 更新
-----

常數和 PHP 類別定義

在類別定義內使用 "define('MY_VAR', 'default value')" 無法如預期般運作。您必須使用 PHP 關鍵字 'const' 並立即使用純量值初始化它——布林值、整數、浮點數、字串(或 PHP 5.6+ 中的陣列)。

<?php

define
('MIN_VALUE', '0.0'); // 正確 - 在類別定義外部有效。
define('MAX_VALUE', '1.0'); // 正確 - 在類別定義外部有效。

//const MIN_VALUE = 0.0; 正確 - 在類別定義內外皆有效。
//const MAX_VALUE = 1.0; 正確 - 在類別定義內外皆有效。

class Constants
{
//define('MIN_VALUE', '0.0'); 錯誤 - 僅在類別定義外部有效。
//define('MAX_VALUE', '1.0'); 錯誤 - 僅在類別定義外部有效。

const MIN_VALUE = 0.0; // 正確 - 在類別定義內部有效。
const MAX_VALUE = 1.0; // 正確 - 在類別定義內部有效。

public static function getMinValue()
{
return
self::MIN_VALUE;
}

public static function
getMaxValue()
{
return
self::MAX_VALUE;
}
}

?>

#範例 1
您可以像這樣直接存取這些常數
* 完整輸入類別名稱。
* 輸入兩個 (2) 個冒號。
* 完整輸入常數名稱。

#範例 2
因為我們的類別定義提供了兩個 (2) 個靜態函式,您也可以像這樣存取它們
* 完整輸入類別名稱。
* 輸入兩個 (2) 個冒號。
* 完整輸入函式名稱(包含括號)。

<?php

#範例 1:
$min = Constants::MIN_VALUE;
$max = Constants::MAX_VALUE;

#範例 2:
$min = Constants::getMinValue();
$max = Constants::getMaxValue();

?>

類別常數一旦宣告並初始化後,就不能設定為不同的值——這就是為什麼類別定義中沒有 setMinValue() 和 setMaxValue() 函式的原因——這表示它們是唯讀且靜態的(由所有類別實例共享)。
gried at NOSPAM dot nsys dot by
8 年前
讓我們來詳述 storm 關於使用未定義常數的評論。他聲稱「未定義的常數會被評估為 true...」的說法同時是對也是錯的。如同文件中進一步說明的:「如果您使用未定義的常數,PHP 會假設您的意思是常數的名稱本身,就像您以字串方式呼叫它一樣...」。所以,是的,當直接存取未定義的全局常數時,它會被解析為等於所搜尋常數名稱的字串(就像 PHP 假設程式設計師忘記了單引號並自動修正一樣),而任何非零非空的字串都會轉換為 True。

有兩種方法可以防止這種情況:
1. 永遠使用 constant('CONST_NAME') 函式來獲取常數值(順帶一提,它也適用於類別常數 - constant('CLASS_NAME::CONST_NAME'));
2. 只使用類別常數(在類別內使用 const 關鍵字定義),因為它們在找不到時不會轉換為字串,而是拋出例外(致命錯誤:未定義的類別常數)。
katana at katana-inc dot com
22 年前
警告:在 heredoc 語法 (https://php.dev.org.tw/manual/en/language.types.string.php) 中使用的常數不會被解釋!

編者註:這是事實。PHP 無法在 heredoc 區塊中區分常數與其他任何字串。
warwick dot jm dot barnes at gmail dot com
4 年前
文件中說:「您可以在程式碼中的任何位置存取常數,而無需考慮作用域」,但值得注意的是,const 宣告必須出現在使用該常數的程式碼之前。

這段程式碼無法運作(使用 PHP 5.4)
<?php
foo
();
const
X = 1;
function
foo() {
echo
"X 的值: " . X;
}
?>
結果:「X 的值: X」

但這段程式碼可以運作
<?php
const X = 1;
foo();
function
foo() {
echo
"X 的值: " . X;
}
?>
結果:「X 的值: 1」

這可能會造成混淆,因為您可以參考出現在原始碼檔案後面位置的函式,但不能參考常數。即使 const 宣告是在編譯時處理的,但它的行為有點像是在執行時處理的。
hafenator2000 at yahoo dot com
19 年前
PHP 模組也會定義常數。請務必避免常數名稱衝突。我能想到的有兩種方法可以做到這一點。
首先,在您的程式碼中,請確保常數名稱尚未被使用。例如:<?php if (! defined("CONSTANT_NAME")) { Define("CONSTANT_NAME","Some Value"); } ?> 當您開始考慮衝突處理以及其影響時,這可能會變得複雜。
其次,毫無例外地為所有常數名稱加上一些前綴,例如:<?php Define("SITE_CONSTANT_NAME","Some Value"); ?>

或許開發人員或文件維護者可以建議一個好的前綴,並要求模組開發者避免在模組中使用該前綴。
ewspencer at industrex dot com
21 年前
我發現使用串接運算子有助於區分常數的值賦值。例如,在全域設定檔中設定常數

<?php
define
('LOCATOR', "/locator");
define('CLASSES', LOCATOR."/code/classes");
define('FUNCTIONS', LOCATOR."/code/functions");
define('USERDIR', LOCATOR."/user");
?>

之後,我可以在呼叫常數值用於靜態結構(例如 require() 呼叫)時使用相同的慣例

<?php
require_once(FUNCTIONS."/database.fnc");
require_once(
FUNCTIONS."/randchar.fnc");
?>

以及動態結構,典型的值賦值給變數

<?php
$userid
= randchar(8,'anc','u');
$usermap = USERDIR."/".$userid.".png";
?>

以上慣例對我來說很有效,並且有助於產生自文件化的程式碼。

-- Erich
Andreas R.
17 年前
如果您正在尋找預定義的常數,例如
* PHP_OS(顯示 PHP 編譯的作業系統;php_uname('s') 可能更適合),
* DIRECTORY_SEPARATOR(Windows 上為 "\\",Linux 上為 '/',...)
* PATH_SEPARATOR(Windows 上為 ';',Linux 上為 ':',...)
它們在附錄中「保留字列表」下的「預定義常數」中
https://php.dev.org.tw/manual/en/reserved.constants.php
而後兩者也在「目錄函數」中提到
https://php.dev.org.tw/manual/en/ref.dir.php
Raheel Khan
9 年前
類別常數預設為公開 (public),但不能指定可見度,否則會產生語法錯誤。

<?php

class constants {

const
MAX_VALUE = 10;
public const
MIN_VALUE =1;

}

// 這可以正常運作
echo constants::MAX_VALUE;

// 這會回傳語法錯誤
echo constants::MIN_VALUE;
?>
storm
19 年前
未定義的常數在使用不正確時會被評估為真 (true)。例如,假設您有以下程式碼:

settings.php
<?php
// 除錯模式
define('DEBUG',false);
?>

test.php
<?php
include('settings.php');

if (
DEBUG) {
// 顯示一些敏感資料
}
?>

如果因為某些原因 settings.php 沒有被包含,DEBUG 常數未被設定,PHP 仍然會印出敏感資料。解決方案是明確地評估它,像這樣:

settings.php
<?php
// 除錯模式
define('DEBUG',0);
?>

test.php
<?php
include('settings.php');

if (
DEBUG == 1) {
// 顯示一些敏感資料
}
?>

現在它就能正常運作了。
To Top