Q. 投稿内にある最初の画像のURLでなく「ID」を取得したい|WPのFAQ

WordPressのカスタマイズにおいて、記事一覧のアイキャッチ等として利用するために投稿内(post_content)で「最初に使用されている画像の取得したい」、ということはよくあります。

この場合、画像の「URL」を取得する方法は割とメジャーなのですが、最近のWPの傾向として画像は「ID」で処理するほうが色々と使い勝手が良かったりします。

そこで今回は「投稿内にある最初の画像のURLでなく”ID”を取得したい」という疑問にお答えします。


A. 正規表現検索で記事内から「画像ID」を抽出するのがたぶんラク

WordPressではメディアライブラリ経由の画像を記事に挿入した場合、「wp-image-[画像ID]」というクラス名が自動で付与されます。

なので、

preg_match_all( '/class=[\'"].*wp-image-([0-9]+).*[\'"].*>/i', [$投稿本文], $matches );

という感じで、投稿本文(post_content)を取得し、それに正規表現検索をかけて[画像ID]部分のみを取得してあげるのがたぶん一番ラク。

ちなみにですが、preg_match_all は微妙にクセのある関数で、値は戻り値ではなく、第3パラメータで指定した変数 $matches に配列として格納される。しかも配列の最初には「パターン全体にマッチした文字列」が格納されるため、「投稿の最初にある画像IDを取得する」ためには

$image_id = $matches[1][0];

とする必要があります。

面倒なので関数化すると・・・

サクッと使いたい方のためにサクッと関数化していきます。

/* -------------------------------------------
/* WPで投稿内にある最初の画像のIDを返す
/*
/* @param int $post_id 投稿ID(未設定ならget_queried_object()より取得)
/* @return mix $image_id 取得した画像ID(取得できない場合はfalse)
------------------------------------------- */
function match_first_image_id( $post_id = false ) {

if ( !$post_id ) {
  // 引数がない場合、現在のクエリから投稿オブジェクトの取得を試みる
  $post_obj = get_queried_object(); 
  $post_content = $post_obj->post_content;
}
else {
  // 引数でポストIDが渡された場合はget_postでコンテンツを取得
  $post_obj = get_post( $post_id );
  $post_content = $post_obj->post_content;
}

// 正規表現検索でコンテンツ内の画像IDを取得
preg_match_all( '/class=[\'"].*wp-image-([0-9]+).*[\'"].*>/i', $post_content, $matches );

// $matches[0]にはパターン全体にマッチした文字列が入る点に注意
$image_id = $matches[1][0];

// IDが取れない場合はfalseを返す
if( !$image_id ){
 return false;
}

return $image_id;
}

パラメータとして「投稿ID(ポストID)」を渡します。
また戻り値は該当する画像IDがあればそれを、ない場合は false を返します。

基本、引数(パラメータ値)を渡さなくても get_queried_object() で投稿オブジェクトを取得してくるためたぶん動く?はず?。

ただサブループなどで使う場合は念の為 get_the_ID() や $post->ID 等で明示的に投稿IDを引数に渡してあげるほうが吉、かと。

使い方のコツ

戻り値で取得した画像IDは wp_get_attachment_url() や wp_get_attachment_image() に渡してあげればテーマやプラグインなどにも画像を埋め込み易くなるのではないかとおもいます。

特に wp_get_attachment_image( ) はレスポンシブ対応の画像コードを自動で出力してくれるため余計な手間がかからずおすすめです。