3.

PHP「Use of undefined constant - assumed」警告の原因と対処(PHP 8 でエラー化)

編集
この記事の要点
  • PHP の警告「Use of undefined constant XXX - assumed 'XXX'」。PHP 7 では Warning、PHP 8 で Fatal Error
  • 原因: クォート忘れの文字列リテラル$_POST[name] のように書くと PHP が「name は定数か?」と探し、無いので文字列扱いにする
  • 対処: 必ずクォートする$_POST['name'] / $arr['key']
  • 本当に定数を使いたい場合は define('XXX', 'value') または const XXX = 'value'
  • PHP 8 移行時に最も多発する非互換警告の一つ。自動修正は Rector / PHP CS Fixer を活用

このエラーの概要

PHP コードで配列キーや単純な識別子をクォートし忘れたとき、PHP 7 系では警告、PHP 8 系では Fatal Error が出ます:

仕組み: PHP のパーサは識別子 name を見ると、まず「定数として定義されているか?」を探します。定数が見つかればその値、見つからなければ「これは文字列リテラルだろう」と推測して 'name' として扱う、というレガシー仕様がありました。これが PHP 8 で正式に廃止されました。

原因の典型パターン

悪い例正しい例説明
$_POST[name]$_POST['name']連想配列キーは必ずクォート
$arr[id]$arr['id']同上
echo helloecho '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 全体を下げると他のバグを見逃します。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. Fatal error: Maximum execution time of 30 seconds exceeded in...
  2. Fatal error: Uncaught Error: Cannot use object of type stdClass as array in ...
  3. Warning: Use of undefined constant ... - assumed '...' (this will throw an Error)
  4. ERROR: Call to undefined method Maatwebsite\Excel\Excel::load()
  5. Maximum execution time of 30 seconds exceeded
  6. Your requirements could not be resolved to an installable set of packages. ... To enable extensions, verify that they are enabled in your .ini files:
  7. could not find driver
  8. the requested PHP extension mbstring is missing from your system.
  9. the requested PHP extension dom is missing from your system.
  10. A non well formed numeric value encountered
  11. Warning: Cannot modify header information - headers already sent by ...
  12. php_network_getaddresses: getaddrinfo failed: Name or service not known
  13. XMLWriter::openUri(): Unable to resolve file path
  14. Object of class stdClass could not be converted to string
  15. Class 'Google_Service_Youtube' not found