「0」エラーの構造
JavaScriptを記述し、PHPハンドラーを設定して、リクエストを送信しました。しかし、期待していたデータの代わりに、ブラウザのコンソールには「0」という孤独な1文字が表示されています。これは、WordPress AJAX APIを使用する際に開発者が直面する最も頻繁な障害の1つです。
ご安心ください。これはWordPressコアのバグではありません。これはadmin-ajax.phpからのデフォルトのレスポンスです。スクリプトが一致するフックを見つけずに実行を終了した場合、あるいは関数の最後に到達しても停止の指示がない場合、WordPressは0を出力してプロセスを終了します。
なぜWordPressはデフォルトで0を返すのか
admin-ajax.phpファイルは、中央ルーターとして機能します。そのファイルの最後で、WordPressはwp_die('0')を実行します。これはキャッチオール(すべてを拾う仕組み)として機能します。リクエストが登録されたアクションをトリガーできなかった場合、または関数が実行されたものの明示的に「終了(die)」しなかった場合、スクリプトはこの最終行に到達し、JavaScriptのsuccessコールバックに0を返します。
ステップ1:フックの登録を確認する
最も多い原因は、アクションフックの欠落や入力ミスです。WordPressでは、AJAXアクションをサイト全体で機能させるために、2つの特定のフックが必要です。1つしか登録していない場合、ユーザーの半分でコードが失敗することになります。
functions.phpまたはプラグインファイルを開き、以下の2行を確認してください。
// ログイン済みユーザー用
add_action('wp_ajax_get_user_stats', 'my_ajax_handler_function');
// ゲストおよびログアウト済みユーザー用
add_action('wp_ajax_nopriv_get_user_stats', 'my_ajax_handler_function');
避けるべき一般的な間違い:
- 「Nopriv」の見落とし: 管理者としてログインした状態でテストしたときは動作しても、
wp_ajax_nopriv_フックを忘れているため、一般の訪問者には機能しません。 - 大文字と小文字の区別: JavaScriptが
action: 'GetUserStats'を送信しているのに、PHPのフックがwp_ajax_get_user_statsを使用している場合、一致しません。
ステップ2:JavaScriptのアクションキーを同期させる
JavaScriptのデータオブジェクトには、actionキーを含める必要があります。この文字列は、WordPressが正しいPHP関数を見つけるための「ID」となります。これは、add_action呼び出しのサフィックス(接尾辞)と正確に一致している必要があります。
// jQueryを使用したJavaScriptの例
$.ajax({
url: ajax_vars.url,
type: 'POST',
data: {
action: 'get_user_stats', // これはPHPフックのサフィックスと正確に一致する必要があります
user_id: 101
},
success: function(response) {
console.log('Server says:', response);
}
});
汎用的なアクション名を送信したり、入力を忘れたりすると、WordPressはどの関数を実行すべきか判断できず、直接その0のレスポンスにつながります。
ステップ3:Nonceとセキュリティエラーをデバッグする
セキュリティチェックが原因で、何も出力されずに失敗することがよくあります。Nonce(ナンス)を使用している場合(使用すべきです)、検証エラーによってロジックに到達する前にスクリプトが終了することがあります。check_ajax_referer()が失敗すると、通常は-1を返しますが、設定によっては0になることもあります。
まず、wp_localize_scriptを使用して、PHPからスクリプトにNonceを渡します。
wp_localize_script('my-app-js', 'ajax_vars', [
'url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('stats_nonce')
]);
次に、PHPハンドラーの最上部でそれを検証します:
function my_ajax_handler_function() {
// Nonceが無効な場合、スクリプトはここで終了します
check_ajax_referer('stats_nonce', 'security');
// データを処理する
$stats = ['views' => 1250, 'likes' => 42];
wp_send_json_success($stats);
}
ステップ4:クリーンな終了を強制する
ロジックが完全に機能していても、WordPressがレスポンスに0を付加してしまうことがあります。これは、データをechoした後にスクリプトを停止しなかった場合に発生します。その結果、{"success":true}0のような不正な形式のJSONになり、JavaScriptエラーの原因となります。
AJAX関数は常に終了コマンドで終わらせてください。最も簡単な方法は、終了処理まで自動で行ってくれるWordPress内蔵のJSONヘルパーを使用することです:
function my_ajax_handler_function() {
// ロジックを実行...
// 推奨:これはJSONヘッダーを送信し、データを出力して、die()を呼び出します
wp_send_json_success($data);
// HTMLレスポンスの場合の代替案:
// echo "<p>Update complete!</p>";
// wp_die();
}
修正を確認する方法
-
ネットワークタブを調査する: DevTools (F12) を開き、「ネットワーク」タブを確認します。「XHR」でフィルタリングしてください。
-
ステータスコードを確認する: リクエストが成功すると、
200 OKステータスが返されるはずです。 -
生のレスポンスを読み取る:
レスポンスが0: フックが一度もトリガーされていません。アクション名を再確認してください。
- レスポンスが-1: セキュリティエラーです。Nonceが欠落しているか、期限切れである可能性があります。
- レスポンスにデータ + 0が含まれている:
wp_die()またはwp_send_json()の呼び出しを忘れています。
素早いデバッグのためのプロのヒント
- フロントエンドのギャップ: WordPress管理画面では
ajaxurl変数が常に利用可能ですが、公開フロントエンドでは利用できません。wp_localize_scriptを使用して手動で定義する必要があります。 - サイレントPHPエラー: コードに構文エラーがある場合、AJAXコールが空のレスポンスや500エラーを返すことがあります。
wp-content/debug.logをチェックして、隠れたPHPクラッシュを特定しましょう。 - 余分な空白を避ける: PHPファイルの閉じタグ
?>の後に空行がないことを確認してください。これらの目に見えないスペースがAJAXレスポンスに注入され、JSONを壊す可能性があります。

