画像の情報を取得したいのだが…
wordpressの関数
wordpressではさまざまな関数があり、欲しい情報をカバーする関数はたいてい用意されています。
だから関数を知れば知るほどやれることは増えるのですが、いかんせんwordpressの関数の一部は余計な情報を引っ張って来る若干おせっかいな面がある事も否めません。
特に画像関係の関数は扱いが難しいかもしれません。
画像の情報は特に多い
画像にはさまざまな情報が付与されています。ファイル名、ディレクトリ、サイズ、キャプション、alt属性、exif情報、どの投稿で使われているか、などなどです。
これらの情報を単体で取り出す関数はおそらくないはずです。
画像の情報の在りか
画像情報のデータベース上の扱い
画像の情報はデータベース上ではwp_postsとwp_postmetaというテーブルに記録されています。付加情報の多くはwp_postmetaの方に記録されている場合が多いです。
画像の情報はキーによって管理されています。なので画像IDと特定のキーさえわかってしまえば(若干のデータ構造の理解が必要になる場面もあり)画像の情報を単体取得することは容易です。
alt属性の在りか
alt属性はwp_postmetaテーブルにおいて「_wp_attachment_image_alt」というキーで記録されています。
wp_postmetaテーブルから何らかの情報を取得するには、get_post_meta()関数を使います。
get_post_meta()関数はカスタムフィールドを取得するための関数ではないか?と気づいた人は鋭いです。
その通りです。じつはカスタムフィールドもwp_postmetaテーブルにキーを介して記録されています。
カスタムフィールドの場合はキーを自分で設定できるのが違いですが、記録のされ方自体はalt情報などと何ら変わりはないのです。
だから、get_post_meta()関数でalt情報を得ることが可能なのです。
もしデータベースの中身を見たいと言うことだったら拙著の記事「wordpressのデータベースをデータベース管理ツールで覗いてみる方法」を参照してもらえると幸いだ。
alt属性やキャプションを単体取得する方法
まず画像のIDを取得
get_post_meta()関数には画像のIDを指定する必要があるので、何らかの方法で画像IDを知る必要があります。
画像関係の関数は色々ありますが、帯に短し襷に長しと言った感じがするので、データベースから直接引っ張ったほうが楽なのではないかと思います。
ここでは画像IDを$wpdbインスタンスのメソッドを使ってデータベースにクエリ発行して取得してみようと思います。
$wpdbはデータベースへのアクセスを簡単にするためにwordpressが用意してくれているクラス・オブジェクトです。newしなくてもwordpress側でオブジェクトを作っているので活用させてもらいましょう。
投稿に使われている画像のIDをすべて取得
画像ID
$wpdbを使って投稿内の画像のIDを取得するコードは以下だ。
$post_id = get_the_ID();
$attachment_ID = $wpdb->get_results("SELECT ID FROM wp_posts WHERE post_parent='{$post_id}' AND post_type='attachment'");
このコードの戻り値は配列になります。
キャプションや説明
ちなみに画像の「キャプション」はwp_postsのpost_exceptに記録されています。このpost_exceptは投稿でいうなら「抜粋」が入るところです。画像の場合はキャプションとして使われます。
さらに言うと、画像の「説明」は、wp_postsのpost_contentに記録されています。これは投稿ではおなじみの投稿本文が入っているところです。
もし、alt属性だけでなく、キャプションや説明を一緒にもしくは単体で取得したい場合は以下の様にするといいでしょう。
画像ID、キャプション、説明を一緒に取得する
$post_id = get_the_ID();
$attachment_ID = $wpdb->get_results("SELECT ID,post_content,post_excerpt FROM wp_posts WHERE post_parent='{$post_id}' AND post_type='attachment'");
この場合戻り値は多次元配列となる。
画像IDとキャプション
$post_id = get_the_ID();
$attachment_ID = $wpdb->get_results("SELECT ID,post_excerpt FROM wp_posts WHERE post_parent='{$post_id}' AND post_type='attachment'");
画像IDと説明だけ
$post_id = get_the_ID();
$attachment_ID = $wpdb->get_results("SELECT ID,post_content FROM wp_posts WHERE post_parent='{$post_id}' AND post_type='attachment'");
画像のalt属性を取得
さてこれで投稿内の画像IDを取得できましたので、あとはループで回して画像のalt属性を取得していきます。
先ほど$wpdb->get_resultsで取得した値はありがたいことにオブジェクトになっています。データベースのコラム名をそのままプロパティ名にしてくれているので、以下の様にアクセスすることが出来きます。
各値のアクセス
//$iはカウンタとして
$attachment_ID[$i]->ID;
$attachment_ID[$i]->post_content;
$attachment_ID[$i]->post_excerpt;
ループにするとこんな感じでしょうか。
for($i = 0 , $count = count($attachment_ID) ; $i < $count ; $i++){
$attachment_alt[] = get_post_meta( $attachment_ID[$i]->ID , "_wp_attachment_image_alt");
}
目的に合わせて、配列を再構築したり、foreachなどを使ってもいいと思います。
注意点
複数の投稿で使われている画像に関しては、ペアレント情報が「追加」では無く「上書き」になるようなので、どうやら一番新しい投稿でしか繋がりが追えないようです。
なので複数投稿で使用の画像の場合上記のコードでは引っ張ってこれません。
対応としては、同一の画像でも投稿に使う度にアップロードする必要があるようです(つまり別IDにしてしまうということ)。
また記データベースに画像のペアレント情報が書きこまれないような特殊な方法で投稿に画像を挿入した場合も、このコードでIDを取得することはできません。例えばnoimage画像をfunctions.phpで定義した関数から挿入する場合などです。
これらの場合、投稿内のURLを正規表現で引っ張り、それを元にデータベースからIDを取得するという面倒な手順を踏むことになるかとお思います。
これはとても面倒なので、できるだけ画像の使い方はシンプルにしておくのが良いかと思います。(noimage画像を引っ張ってくる必要はあまりないように思えるが)
まとめ
とかく混乱しがちなwordpressの画像関係ですが、直接データベースから情報を取得する荒業を使うと意外と簡単になんでも取得できてしまいます。
冒頭でwordpressの関数をdisりましたが、それでもwordpressは良くできていると思います(おべっか)。@MINOなどはすぐ$wpdbに頼ってしまいますが、やはりwordpress関数を使いこなしてなんぼだと思うので、あまり独自にちょろまかすのは良くないかもしれません。
でもね、クライアントの要求によっては規定の関数では処理できないこともあるのが現状だから…。