WordPressでメニュー・設定が保存できない・一部消える時の対処法

実測 に検証

メニューを保存したら、後半の項目が消えた。カスタムフィールドが一部だけ保存されない。 エラーは出ない。「保存しました」と表示される。

原因は WordPress ではなく PHP の max_input_vars です。 上限を超えた分は警告も出さずに捨てられます。実測しました。

実測: 120 個送って 51 個しか届かない

max_input_vars = 50 にして、120 個のフィールドを POST しました。 受け取った側で数えた結果です。

max_input_vars=50
受け取った要素数=51
最初のキー=field1  最後のキー=field51

field52 以降は存在しません。エラーにもならず、$_POST から消えています。

受け取った側から見ると「そもそも送られてこなかった」のと区別がつきません。 WordPress は届いた 51 件を正常に保存し、「保存しました」と表示します。

警告はどこに出るか — debug.log には出ない

これが厄介な点です。警告は出ているのですが、探す場所が普段と違います。

ログ記録
wp-content/debug.log0 件
サーバーの PHP エラーログ1 件

記録されていた内容です。

PHP Warning:  PHP Request Startup: Input variables exceeded 50.
To increase the limit change max_input_vars in php.ini. in Unknown on line 0

PHP Request Startup とあるとおり、WordPress が起動する前に出る警告です。 そのため WP_DEBUG_LOG の仕組みでは拾えません。

「debug.log を見ても何も出ていない」で調査が止まるのはこれが原因です。 見るのはサーバーのエラーログ(レンタルサーバーなら管理画面のエラーログ機能)です。 → PHP のエラーログの場所

項目数と変数の数は一致しない

「メニュー項目は 30 個しかないのに 1000 の上限を超えるのか」と思いますが、 1 項目が複数の変数を消費します。

配列形式で送った場合の実測です。menu-item[N][title] を 120 個送りました。

受け取った要素数=103

配列の入れ子は末端の要素がそれぞれ 1 個として数えられます。 WordPress のメニュー項目は 1 つあたり menu-item-db-id / menu-item-object-id / menu-item-title / menu-item-url / menu-item-target … と 10 個以上の入力を持ちます。

つまり メニュー項目 60〜80 個で既定の上限 1000 に達します。 「50 個を超えたあたりから保存できない」という報告と計算が合います。

同じことがこれらでも起きます。

  • カスタムフィールド(ACF の繰り返しフィールド、テーブル状の入力)
  • 大量のチェックボックスを持つ設定画面
  • 一括編集(投稿一覧でまとめて更新)
  • WooCommerce の商品バリエーション

確認方法

現在値を確認します。

php -i | grep max_input_vars

管理画面の ツール > サイトヘルス > 情報 > サーバー にも表示されます (→ サイトヘルスの読み方)。

疑わしいときは、保存する直前のフォームの入力数を数えます。 ブラウザのコンソールで 1 行です。

document.querySelectorAll('#your-form input, #your-form select, #your-form textarea').length

この数が max_input_vars に近ければ確定です。

対処

php.ini で上げます。

max_input_vars = 5000

共用サーバーでは .user.ini に書ける場合があります(php-fpm 環境)。

; .user.ini をドキュメントルートに置く
max_input_vars = 5000

.htaccessphp_value max_input_vars は Apache(mod_php)でのみ有効です。 php-fpm の環境では無視されます(この点は別記事で実測しています)。

上げられない場合

  • メニューを分割する(フッター用・グローバル用などで複数のメニューにする)
  • 一括編集をやめて小分けに保存する
  • 繰り返しフィールドの行数を減らす

なぜ気づきにくいのか

この障害には、調査を空振りさせる条件が揃っています。

  1. HTTP は 200 で返る — 監視も、ブラウザの開発者ツールも正常に見える
  2. WordPress は「保存しました」と言う — 届いた分は正しく保存している
  3. debug.log に出ない — 起動前の警告なので拾えない
  4. 毎回同じ場所で切れる — 「特定の項目だけ保存できないバグ」だと誤診する

「保存できない」ではなく「保存される量に上限がある」という視点で見ると 一発で当たります。

再現手順

# php.ini で上限を下げる
# max_input_vars = 50
docker compose restart php apache

# 120 個の項目を POST して、受け取った数を数える
# (受信側で count($_POST) を出力するだけのファイルを置く)
data=""; for i in $(seq 1 120); do data="${data}field${i}=v${i}&"; done
curl -s -X POST "http://localhost:8080/probe.php" --data "${data%&}"
# → 受け取った要素数=51

grep "Input variables exceeded" logs/php/php_error.log      # 1 件
grep "Input variables exceeded" src/wp-content/debug.log    # 0 件