◀ 10.

A non well formed numeric value encountered

▶
この記事の要点
  • PHP 7.1〜7.4の A non well formed numeric value encountered(Notice)。PHP 8の警告・例外と区別
  • 原因: 数値に変換できない文字列を算術演算に使っている(例: "10abc" + 5)
  • 対処: 入力の形式・範囲を検証してから変換。キャストだけで不正な値を切り捨てない
  • PHP 8では先頭だけ数値ならWarning、数値として始まらない文字列の算術演算はTypeError

 

エラー内容

A non well formed numeric value encountered

この文言はPHP 7.1〜7.4で、先頭だけ数値として読める文字列を算術演算に使った際のE_NOTICEです。PHP 8では同じ先頭数値の条件はE_WARNINGのA non-numeric value encounteredとなり、数値として始まらない文字列の算術演算はTypeErrorになります。実行したPHP版と入力値を分けて調べてください。

発生条件 / 原因

  • 数値に変換できない(先頭が数値だが末尾に非数字が含まれる)文字列を四則演算の対象にしたとき
  • 例: "10abc" + 5 → 値は 15 になるが、PHP 7.4ではNotice、PHP 8.5ではWarningが出る
  • 例: "1.5kg" * 2 → 値は 3 になるが、PHP 7.4ではNotice、PHP 8.5ではWarning
  • DBから取得した値、HTTPリクエストパラメータ、CSV読み込みなど、外部からの文字列を直接演算しているケース
  • 日付の差分計算で "2024-01-01" をそのまま演算した

対処法

1. 明示的に数値型へキャストする

以下は変換の例として残します。入力検証の代わりにはなりません。10abcが10、abcが0になると、警告が消えても誤った数量を受け入れるおそれがあります。先に形式・単位・範囲を検証してください。

$result = (int) $value + 5;
$result = (float) $value * 2;

2. intval() / floatval() を使う

$result = intval($value) + 5;
$result = floatval($value) * 2;

上の文字列例は先頭の数値部分だけに変換され、算術演算の警告が出なくなります。数値で始まらない文字列も0へ変換され得るので、警告が消えたことだけを正しい入力の証明にしないでください。

3. 事前にバリデーションする

入力値が想定外の文字列の場合は弾く方が安全です。

if (!is_numeric($value)) {
    throw new InvalidArgumentException('numeric required');
}
$result = $value + 5;

4. Laravel等のフレームワーク

Laravelのrequest()->integer()は整数への変換であり、入力検証ではありません。Laravel 13でqty=10abcを渡すとinteger(qty)は10でした。Validationで形式と範囲を先に検査し、成功後に変換します。numericは小数や指数表記も対象になるため、整数数量ならintegerとmin/maxなど、用途に合うルールを選んでください。

$request->validate(['qty' => 'required|integer|min:1']);
$qty = $request->integer('qty');

PHPバージョン別の挙動

PHPバージョン挙動
PHP 7.0以前警告なしで暗黙変換
PHP 7.1 – 7.4「A non well formed numeric value encountered」E_NOTICE(先頭だけ数値の文字列)。完全非数値の演算はE_WARNING
PHP 8.0以降部分数値はWarning、完全に非数値はTypeError

注意点

  • Notice/Warningは通常のPHPでは継続し得るが、フレームワークのエラーハンドラが例外へ変換する場合もある。ログと実際の停止条件を確認する
  • PHP 8では完全非数値の算術演算はTypeError。先頭だけ数値の文字列のWarningとは区別する
  • error_reporting で抑制するのではなく、入力値を正しい型にする方向で直す

再現した入力と結果

演算PHP 7.4.33PHP 8.5.1
10abc + 5(文字列)15 / E_NOTICE15 / E_WARNING
1.5kg * 2(文字列)3 / E_NOTICE3 / E_WARNING
abc + 5(文字列)5 / E_WARNINGTypeError
(int)10abc(文字列)10、演算のNoticeなし10、演算のWarningなし

最後の行は文字列の明示変換です。不正な入力を正しくしたのではなく、数値以外の部分を無視した結果です。検証では一時的なエラーハンドラでレベルと文言を記録しました。本番でerror_reportingを下げたり、例外だけ無視して処理を通したりする対処は勧めません。

整数数量なら形式と範囲を検証する

以下は数量を1〜1000の整数に限定する独立例です。小数・指数表記・単位付き文字列・配列・真偽値を数量として受け入れません。01のような表記もFILTER_VALIDATE_INTの規則に従って判定されるため、許可する入力形式は業務仕様で決めてください。

<?php

function parseQuantity($value): int
{
    if (!is_int($value) && !is_string($value)) {
        throw new InvalidArgumentException('Quantity must be an integer or integer string');
    }
    $quantity = filter_var($value, FILTER_VALIDATE_INT, [
        'options' => ['min_range' => 1, 'max_range' => 1000],
    ]);
    if ($quantity === false) {
        throw new InvalidArgumentException('Quantity must be between 1 and 1000');
    }
    return $quantity;
}

// Example: parseQuantity('10') returns 10; parseQuantity('10abc') throws.

parseQuantity(10)と文字列10は成功し、10abcや1.5kgは例外になります。小数の測定値などは、この数量用関数を使い回さず、単位・小数点・許容範囲を別に設計します。is_numericは数値文字列かの判定であって、正の整数数量や上限を保証するものではありません。

Laravelで検証してから取り出す例

元のmin:1例に上限も付ける場合のコントローラ断片です。実際の上限は業務仕様へ合わせてください。

$request->validate(['qty' => 'required|integer|min:1|max:1000']);
$qty = $request->integer('qty');

Laravel 13のValidatorで文字列10は成功し、10abc・0・-1・1.5・1001は失敗することを確認しました。元のコード例は維持し、変換と入力検証の違いを補足しています。

日付や単位付きデータは数値変換しない

2024-01-01のような日付文字列をキャストすると年の数値だけを読むなど、警告が消えても日数計算にはなりません。日付は日付として解析し、書式・存在する日付・タイムゾーンを検証してから差分を求めます。kgや通貨記号も無条件に除去せず、入力仕様に沿って解析してください。

今回の確認範囲はPHP 7.4.33 / 8.5.1の演算・警告レベル・変換、数量関数の正常2/異常13ケース、Laravel 13の変換と検証6ケースです。PHP 7系は保守用の比較で、新規導入は勧めません。実システムのすべての演算箇所・HTTPエラー処理は未検証です。

公式資料: PHPの数値文字列と版による違い、Laravelの整数入力取得、Laravelの入力検証(2026年10月確認)。

子ページ

子ページはありません

同階層のページ
  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