【WordPress】記事の最初の画像を自動でアイキャッチに設定する方法

【WordPress】記事の最初の画像を自動でアイキャッチに設定する方法 WordPress

WordPressではアイキャッチ画像を設定することで、記事一覧やSNSでの表示を魅力的にできます。ただし、手動で設定するのが面倒だったり、過去の記事にアイキャッチがないという悩みもあるでしょう。

この記事では、投稿本文中の最初の画像を自動でアイキャッチに設定する方法を紹介します。

スポンサーリンク

自動で最初の画像をアイキャッチに設定するコード

以下のコードを functions.php に追記します。

functions.php:本文の最初の画像を自動でアイキャッチに設定
function auto_set_post_thumbnail_from_first_image($post_id) {
  // 自動保存・リビジョン・ゴミ箱は除外
  if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
  if (wp_is_post_revision($post_id) || get_post_status($post_id) === 'trash') return;

  // 対象の投稿タイプ(必要に応じて追加)
  $allowed_post_types = array('post', 'your_custom_post_type'); // ←カスタム投稿タイプをここに追加

  if (!in_array(get_post_type($post_id), $allowed_post_types)) return;

  // すでにアイキャッチがある場合はスキップ
  if (has_post_thumbnail($post_id)) return;

  // 本文から最初の画像URLを抽出
  $post = get_post($post_id);
  if (!$post) return;
  $content = $post->post_content;

  if (preg_match('/<img[^>]+src=["\']([^"\']+)["\'][^>]*>/i', $content, $matches)) {
    $image_url = $matches[1];
    $attachment_id = attachment_url_to_postid($image_url);

    if ($attachment_id) {
      set_post_thumbnail($post_id, $attachment_id);
      return;
    }
  }

  // 最初の画像が見つからなかった場合のデフォルト画像処理(任意)
  // 使わない場合は 0 のままにしておく(設定するとその投稿のIDが常に適用される)
  $default_image_id = 0; // 使う場合はメディアに登録された画像のIDに書き換える
  if ($default_image_id) {
    set_post_thumbnail($post_id, $default_image_id);
  }
}
add_action('save_post', 'auto_set_post_thumbnail_from_first_image');
正規表現の貪欲マッチで「最後の画像」を取得してしまう落とし穴
よく紹介される実装では.+.*を使った正規表現が使われますが、本文に画像が2枚以上あると意図に反して最後の画像を取得してしまいます。実際にPHPで検証した結果は以下の通りです。
NG:画像が複数あると最後の画像を取得してしまう
preg_match('/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $content, $matches);
// $content = '<img src="A.jpg"><p>text</p><img src="B.jpg">'
// -> $matches[1] は "B.jpg"(最後の画像。誤り)
OK:[^>]で属性の範囲を区切り最初の画像を正しく取得
preg_match('/<img[^>]+src=["\']([^"\']+)["\'][^>]*>/i', $content, $matches);
// 同じ $content で -> $matches[1] は "A.jpg"(最初の画像。正しい)
デフォルト画像IDは設定しない限り0のままにする
最初の画像が見つからなかった場合のフォールバックとして固定の画像IDを使いたい場合のみ$default_image_idを書き換えてください。ここを不用意な数値(例: 存在確認していないID)のままにすると、本文に画像が無いすべての投稿に、無関係な画像がアイキャッチとして問答無用で設定されてしまいます。使わない場合は0のままにしておけば、この処理は安全にスキップされます。

デフォルト画像を設定するには?

set_post_thumbnail() に渡すIDは、WordPressにアップロードされた画像の 添付ファイルID です。

IDの確認方法

1.管理画面 → メディア → 画像を選択
2.ブラウザのアドレスバーに表示される post=数字 がその画像のIDです。

過去の記事に一括で適用する方法

この処理は「投稿の保存時」に実行されるため、すでに公開済みの投稿には反映されません。以下のようなスクリプトを一時的に管理画面用ファイルなどに追加して、一括で再実行することができます。

管理画面用ファイルなどに一時的に配置して実行
// 管理画面などに一時的に記載して実行し、後で削除してください
function apply_thumbnail_to_existing_posts() {
  $args = array(
    'post_type' => array('post', 'your_custom_post_type'),
    'post_status' => 'publish',
    'posts_per_page' => -1,
    'meta_query' => array(
      array(
        'key' => '_thumbnail_id',
        'compare' => 'NOT EXISTS',
      )
    )
  );
  $query = new WP_Query($args);

  foreach ($query->posts as $post) {
    auto_set_post_thumbnail_from_first_image($post->ID);
  }

  echo '処理が完了しました。対象投稿数:' . count($query->posts);
}
// apply_thumbnail_to_existing_posts(); // ← 必要なときだけ有効化

⚠ 実行後はセキュリティやパフォーマンスの観点から、必ずこの関数の呼び出しをコメントアウトまたは削除してください。

関連記事

よくある質問(FAQ)

Q記事保存時に最初の画像を自動でアイキャッチに設定するには?
Asave_postフックでhas_post_thumbnail()を確認し、アイキャッチがない場合に本文から画像URLを抽出し、attachment_url_to_postid()でIDを取得してset_post_thumbnail()でアイキャッチを設定します。複数画像がある場合は[^>]でタグの範囲を区切った正規表現を使い、最初の画像を確実に取得します。
Q記事内の画像がWordPressのメディアライブラリにない外部画像の場合はどうなりますか?
Aattachment_url_to_postid()は外部URLには対応していません。この場合はmedia_sideload_image()でサーバーに画像をダウンロードしてメディアライブラリに追加してからアイキャッチとして設定する処理が必要です。
Qアイキャッチの自動設定を特定の投稿タイプにのみ適用するには?
Asave_postフックのコールバックでget_post_type($post_id)を確認し、対象の投稿タイプの場合のみ処理を実行します。

まとめ

記事本文の最初の画像を自動でアイキャッチに設定することで、投稿のビジュアル品質を保ちながら作業効率もアップします。とくに投稿数が多いサイトでは、この仕組みを導入することで更新の手間を大きく削減できます。正規表現の貪欲マッチとデフォルト画像IDの扱いに注意しながら、ぜひ活用してみてください。