PHP 入門

PHP 定数 (Constants)

定数(Constants)は、単純な値を保持するための識別子です。その名の通り、一度定義されると、スクリプトの実行中にその値を変更したり、定義を取り消したりすることはできません。変数との最大の違いは、その値が固定されており、不変(イミュータブル)である点にあります。

PHP では主に 2 つの方法で定数を定義できます:define() 関数と const キーワードです。

1. define() 関数の使用

define() はグローバル関数であり、ランタイム(実行時)に定数を定義するために使用されます。クラス定義の外で使用され、スクリプト全体からアクセス可能なグローバル定数を定義するのに適しています。

define() の構文は以下の通りです:

define(string $name, mixed $value, bool $case_insensitive = false): bool
  • $name: 定数の名前。慣習として、すべて大文字の英字とアンダースコア(_)で命名します。
  • $value: 定数の値。スカラー値(整数、浮動小数点数、文字列、ブール値)、配列、またはリソースを指定できます。
  • $case_insensitive: オプションのブール値引数。true に設定すると大文字小文字を区別しません。デフォルトは false です。ただし、モダンな PHP 開発ではコードの混乱を招くため、true の使用は強く非推奨とされています。

define() で定義された定数は、常にグローバルスコープで有効です。

1.1 define() の基本例

<?php
// アプリケーション名を保持する、大文字小文字を区別する定数を定義
define('APP_NAME', 'マイ・スーパーアプリ'); 

// データベースホストの定数を定義
define('DB_HOST', 'localhost'); 

// 最大ファイルサイズ(バイト単位)を定義
define('MAX_FILE_SIZE', 1024 * 1024 * 5); // 5 MB 

echo 'アプリケーション名: ' . APP_NAME . '<br>';
echo 'データベースホスト: ' . DB_HOST . '<br>';
echo '最大ファイルサイズ: ' . MAX_FILE_SIZE . ' バイト<br>'; 

// 既存の定数を再定義しようとすると、致命的エラー (Fatal error) が発生します
// define('APP_NAME', '別のアプリ'); // この行はエラーになります 

// 存在しない定数へのアクセス
// echo NON_EXISTENT_CONSTANT; // Notice 警告がスローされ、何も出力されません
?>

この例では、APP_NAMEDB_HOSTMAX_FILE_SIZE が定数として定義されています。一度定義されると、それらの値を後から変更することはできません。

1.2 define() と配列

PHP 7 以降、define() を使用して配列の値を保持する定数を定義できるようになりました。

<?php
// 許可される画像タイプを保持する配列定数を定義
define('ALLOWED_IMAGE_TYPES', ['image/jpeg', 'image/png', 'image/gif']); 

// 配列定数内の特定の要素にアクセス
echo '最初の許可タイプ: ' . ALLOWED_IMAGE_TYPES[0] . '<br>'; 

// 配列定数をループで処理
echo 'すべての許可画像タイプ:<br>';
foreach (ALLOWED_IMAGE_TYPES as $type) {
    echo '- ' . $type . '<br>';
}
?>

この例は、固定されたリスト値を保持する際に配列定数が非常に有用であることを示しています。

1.3 条件文内での define() の使用

define() を使用する大きなメリットの 1 つは、条件分岐(if 文など)の内部で実行できる点です。これにより、特定の条件(環境設定など)に基づいて動的に定数を定義できます。

<?php
$environment = 'development'; // 'production' (本番環境), 'staging' (テスト環境) など 

if ($environment === 'development') {
    define('DEBUG_MODE', true);
    define('API_BASE_URL', 'http://dev.api.example.com');
} else {
    define('DEBUG_MODE', false);
    define('API_BASE_URL', 'https://api.example.com');
} 

echo 'デバッグモード: ' . (DEBUG_MODE ? 'オン' : 'オフ') . '<br>';
echo 'API ベースURL: ' . API_BASE_URL . '<br>';
?>

ここでは、$environment 変数の値に応じて DEBUG_MODEAPI_BASE_URL に異なる値が割り当てられています。これはプロジェクトの構成情報を管理する際の一般的なパターンです。

2. const キーワードによる定数の定義

const キーワードは、コンパイル時(compile time)に定数を定義するために使用されます。そのため、const を使用した定数の宣言は、スクリプトのトップレベルのスコープ、またはクラスやインターフェースの内部(クラス定数については後述)で行う必要があります。

関数、ループ、if 文、または try...catch ブロックの内部で const を使用することはできません。

const の構文はよりシンプルです:

const NAME = value;
  • NAME: 定数の名前。通常はすべて大文字とアンダースコアを使用します。
  • value: 定数の値。スカラー値、配列、リソースを指定可能です。古い PHP バージョン(5.6 未満)では、const の値に式(関数呼び出しや計算など)は使用できませんでしたが、モダンな PHP(PHP 5.6+)ではスカラー式を使用できます。

const で定義された定数は、常に大文字小文字を区別します。

2.1 const の基本例

<?php
// サイトドメインの定数を定義
const WEBSITE_DOMAIN = 'example.com'; 

// デフォルトテーマの定数を定義
const DEFAULT_THEME = 'dark'; 

// 数値定数を定義
const PI = 3.14159; 

echo 'サイトドメイン: ' . WEBSITE_DOMAIN . '<br>';
echo 'デフォルトテーマ: ' . DEFAULT_THEME . '<br>';
echo '円周率 PI の値: ' . PI . '<br>'; 

// 関数内部で const を定義しようとすると、パースエラー (Parse error) が発生します
/*
function myFunction() {
    const MY_CONSTANT = 'value'; // Parse error
}
*/
?>

この例では、WEBSITE_DOMAIN などの定数が const で定義されており、その値はコードのコンパイル時に確定します。

2.2 const と式 (PHP 5.6+)

PHP 5.6 以降、const の値の定義にスカラー式(算術演算など)を使用できるようになりました。

<?php
// 算術式を使用した定数の定義
const TWO_PI = 2 * PI; // 注意: PI が事前に定義されている必要があります
const MAX_DIMENSION = 1920 + 1080; 

echo 'PI の 2 倍: ' . TWO_PI . '<br>';
echo '最大寸法の合計: ' . MAX_DIMENSION . '<br>'; 

// 他の定義済み定数を式の中で使用
const APP_VERSION = '1.0';
const APP_FULL_VERSION = APP_VERSION . '.0-beta'; // 文字列の結合 

echo 'アプリのフルバージョン: ' . APP_FULL_VERSION . '<br>';
?>

このように、単純な式や他の定数を利用して最終的な値を算出することができます。

2.3 const による配列定数の定義

define() と同様に、const でも配列を保持する定数を定義できます。

<?php
// アプリケーション設定を保持する配列定数を定義
const APP_SETTINGS = [
    'locale' => 'ja_JP',
    'timezone' => 'Asia/Tokyo',
    'items_per_page' => 20
]; 

echo 'ロケール: ' . APP_SETTINGS['locale'] . '<br>';
echo '1ページあたりの表示数: ' . APP_SETTINGS['items_per_page'] . '<br>'; 

// 配列定数のループ処理
echo '設定リスト:<br>';
foreach (APP_SETTINGS as $key => $value) {
    echo '- ' . $key . ': ' . $value . '<br>';
}
?>

3. define() と const の違い

どちらも定数を作成できますが、いくつか重要な特性の違いがあります:

特性define() 関数const キーワード
定義のタイミングランタイム(実行時)コンパイル時
実行場所関数、ループ、if 文内でも可能トップレベルのスコープのみ
スコープ常にグローバルグローバル、またはクラス内
大文字小文字の区別オプションで変更可能(非推奨)常に区別する
サポートされる値スカラー、配列、リソーススカラー、配列、リソース
式のサポート関数呼び出し等を含むあらゆる式単純なスカラー式のみ(PHP 5.6+)
使用コンテキストグローバル、関数内、if 文内グローバル、クラス/インターフェース内

ベストプラクティス: モダンな PHP 開発では、通常 const を優先して使用すべきです。コンパイル時に処理されるため、わずかながらパフォーマンス上の利点があり、かつ定数の定義規範を厳格に保てるからです。define() を使用するのは、条件分岐や関数内部で定数を定義する必要がある場合や、ランタイムの関数呼び出しの結果を定数値にする必要がある場合に限るのが賢明です。

4. 定数の存在確認

defined() 関数を使用すると、特定の定数がすでに定義されているかどうかを確認できます。これは、重複定義によるエラーを防いだり、定数が未定義の場合にデフォルト値を設定したりする際に非常に便利です。

<?php
// 使用または定義する前に、存在を確認
if (!defined('DB_PASS')) {
    define('DB_PASS', 'secure_password');
} 

echo 'データベースパスワード: ' . DB_PASS . '<br>'; 

// APP_NAME のチェック
if (defined('APP_NAME')) {
    echo 'APP_NAME は定義されています。<br>';
} else {
    echo 'APP_NAME は未定義です。<br>';
}
?>