wordpressの画像に強くなる
wordpressのカスタマイズでは画像を扱うことが結構多いですよね。その為、wordpressの内部で画像がどのように扱われているかをよく知っておく必要があると思います。
今回の記事ではwordpressにおいて画像はどのようにデータベースに記録されているかを説明したいと思います。
データベースを見るに当たっては拙著の記事wordpressのデータベースをデータベース管理ツールで覗いてみる方法が参考になると思います。データベースを見ながら本記事を読んでいただけると面白いのではないかと思います。
画像情報はデータベースに記録される
メディアアップローダを介してアップロードされた画像は、サーバのディレクトリ中に格納されるとともに、wordpressデータベースのwp_postsというテーブルに画像パス(URI)に紐づけてID、ファイル名、アップロード時間などの情報が記録されます。
wp_postsテーブルでの画像データの記録のされ方
パラメータ | 意味 | 値の例 |
---|---|---|
ID | ID | 1501 |
post_author | 投稿者 | 1 |
post_date | 画像をアップロードした日時 | 2015-02-10 12:07:45 |
post_date_gmt | 画像をアップロードした日時 | 2015-02-10 3:07:45 |
post_content | 本文(画像の場合は空白) | |
post_title | 画像のタイトル | 1139150245147 |
post_excerpt | 抜粋文(画像の場合は空白) | |
post_status | 画像の状態 | inherit |
comment_status | open | open |
ping_status | open | open |
post_password | パスワード(設定されていなければ空白) | |
post_name | 画像の名前 | 1139150245147 |
to_ping | ピン先 | |
pinged | ピンバックした履歴 | |
post_modified | 画像を更新した日時 | 2015-02-10 12:07:45 |
post_modified_gmt | 画像を更新した日時 | 2015-02-10 3:07 |
post_content_filtered | 画像の場合は意味なし | |
post_parent | 親投稿(画像が使われている投稿のID) | 1502 |
guid | 画像のパス(URI) | https://unskilled.site/wp-content/uploads/2015/02/1139150245147.jpg |
menu_order | 画像の場合は意味なし | 0 |
post_type | 種類 | attachment |
post_mime_type | コンテンツタイプ | image/jpeg |
comment_count | コメント数 | 0 |
つまり画像IDをからパスやファイル名が引っ張れる状態になるという訳です。wordpressの画像関係の関数の多くは画像IDをキーにしているものが多いです。
また当然ながらメディアアップローダを介さないアップロードはデータベースには登録されないので、wordpressの関数等でハンドリングするのはむずかしくなります。
データベース上での投稿・固定ページ・画像の区分け
wp_postsという名前からわかる通り、このテーブルは画像専用のテーブルではなく、投稿、固定ページも記録されます。投稿(post)か固定ページ(page)か、画像(attachment)か等はこのテーブルのpost_typeに記録されており、この情報で仕分けられています。
IDが飛び飛びになるのはなぜか
記事を公開する場合、前の記事はIDが100だったのに、今回の記事はもうIDが130になっていると不思議に思ったことはないでしょうか?
これはwp_postsテーブルに投稿以外の複数の要素が記録される(画像、リビジョンなど)からであり、投稿IDは連続しないのが普通なので安心してほしいデス。
サムネイルの作成
画像はアップロードした際に、デフォルトであればthumbnail,lmedium,largeと言うサイズの画像が自動的に作られます(元画像はfullというサイズになる)。いわゆるサムネイルですね。
サムネイルは元のファイルがhoge.jpgだとしたら、hoge-150×150.jpgやhoge-300×225.jpgなどといった感じの名前で、元画像と同じディレクトリに入ることになります。
画像の編集
もしwodpress内のツールを使って画像を編集した場合、デフォルトでは内部処理として画像は複製され、複製された方に編集が施されることになります。この処置によって未編集元画像が失われずいつでも復帰させることが可能となっています。
編集画像は元画像がhoge.jpgだとしたら、hoge-e1423544176444.jpgのようなハッシュ値がついたファイル名になります。さらに編集画像を元にサムネイルが新規に作られます。その際サムネイルはhoge-e1423544176444-150×150.jpgなどと言ったファイル名になります。
画像編集をたくさんやると派生画像がどんどんできるということになります。すこし大げさな話ですが、これはサーバ容量を圧迫する原因にもなりえますよ。
画像を編集すると、画像は元画像と編集画像に分かれることになりますが、記事では編集画像がつかわれ、元画像が使われることはないデス。当たり前といえば当たり前なんですが、IDが別途に与えられるわけでもないのにどのように整理しているのでしょうか?
仕組みはこうです。
画像のメタデータにはシリアライズデータとは別に画像の格納されているディレクトリと名前が記録されています。画像を編集した場合、このデータが編集画像のディレクトリと名前に上書きされることになります。
画像を読み込むときにはこのwp_postmetaテーブルを参照するので、元画像のIDからたどると、ディレクトリ&ファイル名は編集画像のものになっているので、元画像が読み込まれることはないのです。なかなかうまくできていますよね。
meta_id | post_id | meta_key | meta_value |
---|---|---|---|
整理ID | 画像ID | 画像のファイル名に関するデータである事を示すキー | ディレクトリ・ファイル名 |
540 | 1501 | _wp_attached_file | 2015/02/1139150245147.jpg |
編集後には以下の様に編集画像のディレクトリ・ファイル名で上書きされる
meta_id | post_id | meta_key | meta_value |
---|---|---|---|
整理ID | 画像ID | 画像のファイル名に関するデータである事を示すキー | ディレクトリ・ファイル名 |
540 | 1501 | _wp_attached_file | 2015/02/1139150245147-e1423544176444.jpg |
サムネイルと編集画像
サムネイルと編集画像のデータベース上の情報は元画像の情報があるwp_postsには無く、元画像のIDに紐づいた形でwp_postmetaという別なテーブルに記録されています。
画像のメタデータ
meta_id | post_id | meta_key | meta_value |
---|---|---|---|
整理ID | 画像ID | 画像のメタデータである事を示すキー | シリアライズデータ(メタデータ) |
541 | 1501 | _wp_attachment_metadata | a:5:{s:5:”width”;i:3008;s:6:”height”;i:2000;s:4:”file”;s:20:…長いので省略 |
このテーブルで、画像IDに紐づけられた形でシリアライズデータとしてすべてのサムネイルサイズの画像情報(サイズ、URI、ファイル名など)格納されています。(元画像のメタデータもこのテーブルに記録されている)
シリアライズデータ
シリアライズデータとは配列やオブジェクトをデータベースに記録する際に使われるデータ形式です。簡単に言うと規則性を持った文字列に変換するといったイメージです。
画像のメタデータを格納しているシリアライズデータは以下のような感じ。
a:5: { s:5:"width"; i:3008; s:6:"height"; i:2000; s:4:"file"; s:20:"2014/11/DSC_0087.jpg"; s:5:"sizes"; a:3:{ s:9:"thumbnail"; a:4:{ s:4:"file"; s:20:"DSC_0087-150x150.jpg"; s:5:"width"; i:150;s:6:"height"; i:150;s:9:"mime-type"; s:10:"image/jpeg"; } s:6:"medium"; a:4:{ s:4:"file"; s:20:"DSC_0087-300x199.jpg"; s:5:"width"; i:300; s:6:"height"; i:199; s:9:"mime-type"; s:10:"image/jpeg"; } s:5:"large"; a:4:{ s:4:"file"; s:21:"DSC_0087-1024x680.jpg"; s:5:"width"; i:1024; s:6:"height"; i:680; s:9:"mime-type"; s:10:"image/jpeg"; } } s:10:"image_meta"; a:10:{ s:8:"aperture"; d:5.5999999999999996447286321199499070644378662109375; s:6:"credit"; s:0:"";s:6:"camera"; s:9:"NIKON D70"; s:7:"caption"; s:0:""; s:17:"created_timestamp"; i:1387209298; s:9:"copyright"; s:0:""; s:12:"focal_length"; s:3:"170"; s:3:"iso"; i:0; s:13:"shutter_speed"; s:5:"0.002"; s:5:"title"; s:0:""; } }
これは画像一枚のシリアライズデータです。長いが読んでもらうと意味は単純なことに気が付いてもらえるかと思います。(s:3やa:4などはデータ型を表している)
元画像の大きさが3008×2008であることや、mediumのサイズが300×199であることが書かれています。またimagemetaには画像のメタデータ、いわゆるExif情報が入っています。
読み出し時にデシリアライズ(もとの配列やオブジェクトの形に戻すこと)が行われ、PHPで扱えるデータになります。もちろんwordpressでは内部でデシリアライズがされているので、私たちがその処理を意識することはほとんどないと思います。
Exif
余談ですがExifは個人情報に当たる場合もあるので、必要ないなら消したほうがいいかと思います。撮影デバイスにも依りますが、撮影場所のGPS情報などもこのExifに入るからです。
wordpressには画像アップロード時にこのExifを消してくれるプラグインがいくつかあるので、興味のある人は調べてみるのをお勧めします。
記事に使われているかどうか
画像が記事に使われているかどうかに関しては、wp_postsのpost_parentに記録されています。記事に画像使われている際、親子関係にあることになる。子(画像)の側のレコードのpost_parentに親(投稿)のIDが入る事で親子関係を維持しています。
ただ@MINOが調べた中で、同じ画像を異なる記事複数に使った場合に、どのような親子関係になるのかが判らなかったです。
というのもpost_parentには親記事のIDがすべて記録されているのかと思いきや、常に一つの値(つまり一つの記事ID、どうやら最初に親になった記事のIDが入るようだ)しか入っていなかったからです。
画像が複数の記事で使われていることがどこで記録されているかが不明なのでなんとも気持ち悪い。
もしかしたら同じ画像を複数の記事で使うということを想定していないのでしょうか?その辺はちょっとよくわからなかったです。
アイキャッチ画像
アイキャッチ画像はデータの関係性だけで表現されています。wp_postmetaテーブルにどの画像がどの記事に対してアイキャッチ画像として設定されているかが記録されます。
通常アイキャッチ画像はfunctions.phpで使うサイズを設定しますが、そのサイズ指定は結局のところ、対象画像のシリアライズデータを読みに行っているということになります。
アイキャッチ画像の記録
meta_id | post_id | meta_key | meta_value |
---|---|---|---|
整理ID | 投稿ID | アイキャッチに設定されている事を示すキー | 画像ID |
501 | 1501 | _thumbnail_id | 932 |
記事内の画像の順番は保障されていない
データベースには記事内の画像の順番について記録しているデータはないようです。
その為、なんらかの理由で画像の順番にこだわる場合はアイデアを練る必要がありますね。もっとも多いのは投稿本文から正規表現でimgタグを引っ張る方法です。
マッチングを上から行えば、投稿内で一番上の画像から順に取得できうるかと思います。
ただこの方法ではimgタグもしくは画像のURLを取得できたとしても、画像の別サイズつまりサムネイルを取得するのが困難。投稿内の画像はおおよそFullサイズで使われているでしょうし、リスト表示などの際はFullサイズでは大きすぎるだろうと思います。
サムネイルはIDから取得することは簡単ですが、URLを元にサムネイルを取得するwordpress関数はおそらく無いです(はず)。なので正規ではない方法でサムネイルに到達しなくてはならないのがやや面倒です。
だからアイキャッチ画像をつかえと言う事なんだろうと思いますが、なぜかアイキャッチ画像を嫌厭している人は多い(ようです)。
まとめ
wordpressはデータベースから攻めると結構理解しやすいのではないかと思っています。データベースのリレーションがwordpressの構造とも言えるし、そこに得手不得手が生まれるかと。
だからどのようにデータが絡んでいるのかを知っておくのは、今後wordpressを使う上で強みになると思います。今回の記事でwordpressの画像についての知識を深めていただくことができましたでしょうか?
wordpressを仕事で使う人も趣味で使う人にも参考になったらこれ幸い。
(@MINOはwordpressを仕事で使っているつもりだが、仕事は無い…)