WordPressでは、カスタムフィールドを活用して投稿に独自の情報を付与することが一般的です。しかし、運用中に「特定の条件を満たす投稿だけ一括で値を変更したい」といったケースが出てくることもあります。
この記事では、カテゴリー・投稿ステータス・公開日などの条件に応じて、投稿のカスタムフィールドを一括で更新する方法を紹介します。
functions.phpで一括更新処理を作成
以下のコードをテーマのfunctions.phpに追加することで、条件に一致する投稿のカスタムフィールドを一括更新する関数を用意します。
function update_custom_field_in_bulk() {
// 一括更新の対象となる投稿を取得(例:特定のカテゴリIDが5の投稿)
$args = array(
'post_type' => 'post',
'posts_per_page' => -1,
'category__in' => array(5),
'post_status' => 'publish',
);
$posts = get_posts($args);
foreach ($posts as $post) {
// カスタムフィールドの値を更新
update_post_meta($post->ID, 'your_custom_field_key', '新しい値');
}
return count($posts);
}
この関数は、カテゴリーIDが5の公開済み投稿に対して、your_custom_field_keyの値を新しい値に一括更新します。
安全に一度だけ実行する方法
この関数をそのまま
add_action('init', 'update_custom_field_in_bulk')でフックすると、サイトへのあらゆるアクセス(訪問者のページ閲覧・管理画面・Ajax・REST APIリクエストすべて)のたびに実行されてしまいます。無制限クエリ(posts_per_page => -1)とupdate_post_meta()の呼び出しが、削除し忘れている間ずっと全リクエストで走り続けることになり、サーバー負荷の原因になります。「一度実行したら削除する」という運用は、実際にアクセスのある本番サイトでは確実に1回だけの実行を保証できません。管理画面にボタンを設置し、クリックしたときだけ実行する方式が安全です。// 管理画面「設定」>「一般」にボタンを設置し、クリックしたときだけ実行する
function render_bulk_update_button() {
if (!current_user_can('manage_options')) return;
$url = wp_nonce_url(admin_url('options-general.php?run_bulk_update=1'), 'run_bulk_update');
echo '<p><a href="' . esc_url($url) . '" class="button">カスタムフィールドを一括更新する</a></p>';
}
add_action('admin_notices', 'render_bulk_update_button');
function handle_bulk_update_request() {
if (!isset($_GET['run_bulk_update'])) return;
if (!current_user_can('manage_options')) return;
check_admin_referer('run_bulk_update');
$updated = update_custom_field_in_bulk();
add_action('admin_notices', function () use ($updated) {
echo '<div class="notice notice-success"><p>' . intval($updated) . '件のカスタムフィールドを更新しました。</p></div>';
});
}
add_action('admin_init', 'handle_bulk_update_request');
「設定」>「一般」画面に表示されるボタンをクリックすると、nonceと権限チェックを経て一括更新が実行されます。実行後はコード自体を削除して構いません。
より柔軟な条件の設定例
以下のような条件で絞り込みも可能です。
// 投稿日が2023年以降、特定の投稿タイプ
$args = array(
'post_type' => 'your_custom_post_type',
'posts_per_page' => -1,
'post_status' => 'publish',
'date_query' => array(
array(
'after' => '2023-01-01',
),
),
'meta_query' => array(
array(
'key' => 'your_custom_field_key',
'value' => '',
'compare' => '=', // 既存フィールドが空文字の投稿のみ(未設定の投稿は含まない)
),
),
);
ここでの'value' => '', 'compare' => '='は、フィールドが存在していて値が空文字の投稿のみを対象にします。フィールドが一度も保存されていない(未設定の)投稿も含めて「空または未設定」を網羅したい場合は、特定のカスタムフィールドが未入力の投稿だけを抽出する方法で解説しているEXISTS/NOT EXISTSのOR結合を使ってください。
WP-CLIでの一括更新もおすすめ
大規模な投稿数がある場合は、WP-CLIを使ってサーバー側でバッチ処理を行うと高速かつ安全です。functions.phpにコードを残す必要もありません。
# 特定のメタキーの値を一括で更新する例(対象の投稿IDを事前に取得しておく)
wp post list --category=5 --post_status=publish --field=ID | \
xargs -I{} wp post meta update {} your_custom_field_key "新しい値"
サーバー操作に慣れている方には特に有効な方法です。
注意点
- 一括更新はバックアップを取った上で実施しましょう。
- functions.phpに一時的なコードを追加する場合は、init等の全リクエストで発火するフックに直接つながず、管理画面ボタンなど明示的なトリガーを用意してください。
- 特定の条件に基づく正確なクエリ設計が重要です。事前にテスト環境で動作確認することを推奨します。
よくある質問(FAQ)
まとめ
特定の条件に応じてカスタムフィールドを一括更新することで、データの整合性維持や運用効率化が可能になります。投稿タイプ・公開日・カテゴリ・既存のカスタムフィールド値などを条件に絞ることで、柔軟な対応ができるのがWordPressの強みです。一括更新の実行は、全リクエストで発火するフックに直接つながず、管理画面ボタンやWP-CLIなど明示的なトリガーを使うようにしましょう。
運用フローの中でこうしたバッチ処理をうまく組み込んで、より快適な管理体制を構築していきましょう。

