2016/10/18 21:25:39

wordpressで画像はどのようにデータベースに記録されているか

wordpress
目次(クリックするとジャンプします)
  • 1:wordpressの画像に強くなる
  • 1.1:画像情報はデータベースに記録される
  • 1.1.1:wp_postsテーブルでの画像データの記録のされ方
  • 1.1.2:データベース上での投稿・固定ページ・画像の区分け
  • 1.1.3:IDが飛び飛びになるのはなぜか
  • 1.2:サムネイルの作成
  • 1.3:画像の編集
  • 1.4:サムネイルと編集画像
  • 1.4.1:画像のメタデータ
  • 1.4.2:シリアライズデータ
  • 1.4.3:Exif
  • 1.5:記事に使われているかどうか
  • 1.6:アイキャッチ画像
  • 1.6.1:アイキャッチ画像の記録
  • 1.7:記事内の画像の順番は保障されていない
  • 2:まとめ

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) http://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に記録されており、この情報で仕分けられています。

pic3

IDが飛び飛びになるのはなぜか

記事を公開する場合、前の記事はIDが100だったのに、今回の記事はもうIDが130になっていると不思議に思ったことはないでしょうか?

これはwp_postsテーブルに投稿以外の複数の要素が記録される(画像、リビジョンなど)からであり、投稿IDは連続しないのが普通なので安心してほしいデス。

サムネイルの作成

画像はアップロードした際に、デフォルトであればthumbnail,lmedium,largeと言うサイズの画像が自動的に作られます(元画像はfullというサイズになる)。いわゆるサムネイルですね。

サムネイルは元のファイルがhoge.jpgだとしたら、hoge-150×150.jpgやhoge-300×225.jpgなどといった感じの名前で、元画像と同じディレクトリに入ることになります。

pic1

画像の編集

もしwodpress内のツールを使って画像を編集した場合、デフォルトでは内部処理として画像は複製され、複製された方に編集が施されることになります。この処置によって未編集元画像が失われずいつでも復帰させることが可能となっています。

編集画像は元画像がhoge.jpgだとしたら、hoge-e1423544176444.jpgのようなハッシュ値がついたファイル名になります。さらに編集画像を元にサムネイルが新規に作られます。その際サムネイルはhoge-e1423544176444-150×150.jpgなどと言ったファイル名になります。

pic2

画像編集をたくさんやると派生画像がどんどんできるということになります。すこし大げさな話ですが、これはサーバ容量を圧迫する原因にもなりえますよ。

画像を編集すると、画像は元画像と編集画像に分かれることになりますが、記事では編集画像がつかわれ、元画像が使われることはないデス。当たり前といえば当たり前なんですが、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を仕事で使っているつもりだが、仕事は無い…)