タイトル: Warning: Use of undefined constant ... - assumed '...' (this will throw an Error)
SEOタイトル: PHP「Use of undefined constant - assumed」警告の原因と対処(PHP 8 でエラー化)
| この記事の要点 |
|
このエラーの概要
PHP コードで配列キーや単純な識別子をクォートし忘れたとき、PHP 7 系では警告、PHP 8 系では Fatal Error が出ます:
仕組み: PHP のパーサは識別子 name を見ると、まず「定数として定義されているか?」を探します。定数が見つかればその値、見つからなければ「これは文字列リテラルだろう」と推測して 'name' として扱う、というレガシー仕様がありました。これが PHP 8 で正式に廃止されました。
原因の典型パターン
| 悪い例 | 正しい例 | 説明 |
|---|---|---|
$_POST[name] | $_POST['name'] | 連想配列キーは必ずクォート |
$arr[id] | $arr['id'] | 同上 |
echo hello | echo 'hello' | 文字列リテラル |
strpos($s, abc) | strpos($s, 'abc') | 関数引数の文字列 |
$tag = a; | $tag = 'a'; or define('a', 'val') | 未定義の識別子 |
対処1: クォートを付ける(基本)
$value) {
echo $item['name']; // ← クォート
}
// 関数引数
$pos = strpos($haystack, 'needle');
$arr = explode(',', $csv);
// クラス定数アクセスは別物(::はOK)
echo MyClass::CONST_NAME; // OK
echo MyClass::$staticProp; // OK
対処2: 本当に定数を使いたい場合
対処3: define vs const の違い
| 項目 | define() | const |
|---|---|---|
| 定義場所 | 関数内・条件分岐内 OK | トップレベル or クラス内のみ |
| 動的な値 | 変数・関数結果 OK | コンパイル時定数式のみ |
| 大文字小文字 | 第3引数 true で無視可(PHP 7.3 で廃止予定) | 常に大小区別 |
| 名前空間 | 第1引数に NS を文字列で書く必要 | 現在の NS に自動所属 |
| パフォーマンス | 遅い(実行時) | 速い(コンパイル時) |
PHP 8 移行時の自動修正
レガシーコードを大量修正する場合は静的解析ツールを使います:
# PHP CS Fixer
composer require --dev friendsofphp/php-cs-fixer
# .php-cs-fixer.dist.php
# setRules([
# '@PSR12' => true,
# 'array_syntax' => ['syntax' => 'short'],
# 'no_unused_imports' => true,
# ])
# ->setFinder(PhpCsFixer\Finder::create()->in(__DIR__ . '/src'));
vendor/bin/php-cs-fixer fix src/
# Rector (PHP 8 自動マイグレーション)
composer require --dev rector/rector
vendor/bin/rector init
# rector.php
# return RectorConfig::configure()
# ->withPhpSets(php82: true)
# ->withRules([
# Rector\Php74\Rector\ArrayDimFetch\ArrayDimFetchToStringRector::class,
# ]);
vendor/bin/rector process src/
PHP のエラーレベル制御
未定義配列キーの関連エラー(PHP 8)
PHP 8.0 以降は未定義配列キーアクセスも警告 → エラー化しています:
1];
// PHP 7: Notice
// PHP 8: Warning
echo $arr['b'];
// 安全なアクセス(PHP 7+)
echo $arr['b'] ?? 'default';
// isset チェック
if (isset($arr['b'])) {
echo $arr['b'];
}
// 配列キー存在確認(null も区別)
if (array_key_exists('b', $arr)) {
echo $arr['b'];
}
// null 安全演算子 (PHP 8.0+)
echo $user?->profile?->name ?? '匿名';
FAQ
Q: PHP 5.x から PHP 8.x にアップグレードしたら大量の Fatal Error
A: Rector の php80 セットでほぼ自動修正できます。手動修正なら grep -rn "\\$_\\(POST\\|GET\\|SESSION\\)\\[[a-zA-Z_]" src/ で抽出。
Q: ライブラリの中で警告が出る
A: 自分のコードでなければライブラリを更新してください。Composer の composer outdated で古いものを確認。古すぎて更新不可ならフォークか置き換え検討。
Q: 警告を一時的に黙らせたい
A: 短期的には @ 抑制演算子(非推奨)。中長期的には根本修正してください。error_reporting 全体を下げると他のバグを見逃します。