定数の基本概念
定数(Constant)は、一度値が割り当てられるとスクリプトの実行を通じて変更が許されないデータ参照です。通常のプログラムフロー内では上書きや削除が不可能であり、どこで宣言されようと自動的にグローバルスコープを有します。既に設定済みの識別子を再度宣言しても、PHPは最初の定義値のみを保持し、警告を出力するのみです。
宣言構文と推奨アプローチ
PHPでは定数を宣言する手段として、define() 関数と const キーワードの2つが用意されています。
// define関数のシグネチャ
// define(string $name, mixed $value, bool $case_insensitive = false): bool
// 基本的な定義例
define('CACHE_DIR', '/tmp/app_cache', true); // 第3引数にtrueを渡すと大文字小文字を区別しない
const APP_NAME = 'MyService';
一般的に、クラス外部の定数定義では構文的に明確な const の使用が推奨されますが、条件分岐やループ内部など実行時の制御フロー内で宣言を行う必要がある場合は define() が必須となります。
define() と const の仕様差異
- スコープと制御構造: PHP 5.3.0以前は
constはクラス内部に限定されていましたが、以降はグローバルでも利用可能になりました。ただし、if、for、関数本体などの中括弧{}で囲まれたブロック内部ではconstは構文エラーとなります。一方、define()は実行時に評価されるため、あらゆる制御構造内で使用可能です。 - パフォーマンスと言語仕様:
constは言語の構文要素であり、コンパイル時に静的に解決されるため処理速度が優れています。define()は関数呼び出しのため、わずかなオーバーヘッドが発生します。 - クラス定数: クラスプロパティと同様にメンバとして定数を定義する場合、
constのみが使用できます。 - 動的な識別子と値の型:
define()は第1引数に文字列連結や変数展開を利用した動的な名前、および式展開による値を渡せます。constは静的なスカラー値(整数、浮動小数点数、文字列、真偽値)のみを許容し、識別子も静的に記述する必要があります。 - 大文字小文字の厳密性:
constは常に大文字小文字を区別します。define()は第3引数をtrueに設定することで非区別モードへ切り替えることができます。
<?php
// グローバルレベルでの静的定義
const API_ENDPOINT = 'https://api.example.com';
define('MAX_UPLOAD_SIZE', 1024 * 1024 * 5);
// 制御ブロック内での定義(defineのみ許可)
if (true) {
// const BLOCK_CONST = 1; // エラー: 実行時ブロック内でconstは使用不可
define('DYNAMIC_FLAG_A', 'enabled');
}
for ($j = 0; $j < 3; $j++) {
// const LOOP_CONST = 2; // エラー
define('PERFORMANCE_LEVEL_' . $j, $j * 100);
}
// 関数内での定義
function initialize_runtime_config() {
// const FUNC_CONST = 3; // エラー
define('RUNTIME_MODE', 'production');
}
// クラス定数の定義
class DatabaseManager {
const CONNECTION_TIMEOUT = 30;
// define('CLASS_CONFIG', 60); // エラー: クラスメンバ定義では使用不可
public function setup() {
// const METHOD_CONFIG = 5; // エラー
define('METHOD_CONFIG', 5);
}
}
定数の参照と動的解決
定数の値を利用する際、通常は識別子をそのまま記述することで参照できます。しかし、識別子の名称が実行時に決定されるケースでは、constant() 関数を用いて文字列から値を動的に解決する必要があります。
<?php
const SYSTEM_VERSION = '2.4.1';
for ($n = 0; $n < 2; $n++) {
define('FEATURE_SWITCH_' . $n, $n === 0);
}
// 直接参照
echo SYSTEM_VERSION;
// 動的参照(constant関数の利用)
for ($n = 0; $n < 2; $n++) {
$key = 'FEATURE_SWITCH_' . $n;
var_dump(constant($key));
}
変数との明確な差異
- 宣言構文: 変数は
$シンボルを接頭語として使用しますが、定数は$を含まず、constまたはdefine()で定義します。 - 値の保持特性: 変数は参照の再代入や
unset()による解放が自由ですが、定数は初期化時に設定された値が変更不可能で、スクリプト終了まで存続します。 - 有効範囲: 変数は宣言されたスコープ(ローカル、関数、クラスなど)に制限されますが、定数は宣言位置を問わず直ちにグローバルに公開されます。
- 許容されるデータ型: 変数は配列、オブジェクト、リソースなどあらゆる型を格納できますが、定数はスカラー値(
int,float,string,bool)に限定されます。