• wp_get_attachment_metadata()は画像寸法と生成済みサイズを読み、実ファイルを別に確認する

wp_get_attachment_metadata()は画像寸法と生成済みサイズを読み、実ファイルを別に確認する

公開日: 執筆:佐藤

wp_get_attachment_metadata()は、添付ファイル投稿に保存されたメタデータを読みます。画像の幅、高さ、元画像の相対パス、生成済みサイズの情報は読めますが、その場所にファイルが残っていることまでは保証しません。

画像が表示されない原因を調べるときは、メタデータの有無と実ファイルの有無を別々に確認します。先に読み取り結果を記録し、原因が決まる前にメタデータの更新や画像の再生成を始めないでください。

wp_get_attachment_metadata()は添付IDから保存済み情報を読む

WordPress 3.9.1の公式Coreでは、wp_get_attachment_metadata()は添付IDに対応する_wp_attachment_metadataを読みます。添付ファイル投稿が見つからない場合や、配列として扱えるメタデータがない場合を考え、返り値を先に調べます。

function example_read_attachment_image_metadata( $attachment_id ) {
	$metadata = wp_get_attachment_metadata( $attachment_id );

	if ( ! is_array( $metadata ) ) {
		return false;
	}

	return array(
		'width'     => isset( $metadata['width'] ) ? (int) $metadata['width'] : 0,
		'height'    => isset( $metadata['height'] ) ? (int) $metadata['height'] : 0,
		'size_names' => ! empty( $metadata['sizes'] ) && is_array( $metadata['sizes'] )
			? array_keys( $metadata['sizes'] )
			: array(),
	);
}

$image_information = example_read_attachment_image_metadata( 123 );

このコードは情報を読むだけです。メタデータを作り直したり、画像ファイルを生成したりはしません。

width、height、file、sizesは同じ対象を示さない

2014年7月1日保存のWordPress公式Codexは、画像のメタデータを次のように説明しています。

キー 読める内容 確認できないこと
width 元画像の幅 テンプレート上の表示幅
height 元画像の高さ テンプレート上の表示高さ
file uploadsディレクトリを基準にした元画像の相対パス その場所にファイルが残っているか
sizes 生成された各サイズのファイル名、幅、高さ、MIMEタイプ 登録済みのすべての画像サイズ名
image_meta 画像から読まれた追加情報 画像の表示可否

WordPressの標準生成処理では、sizesにthumbnailやmediumなどの名前をキーとして、保存できた中間画像の情報が入ります。画像サイズを登録しただけで生成されなかったものや、画像作成後に追加したサイズは、ここへ存在するとは限りません。

反対に、sizesへ項目があっても、バックアップの復元漏れや手動削除によって、対応するファイルが失われている場合があります。メタデータは、ファイルシステムを毎回調べた結果ではありません。

実ファイルはget_attached_file()とis_file()で確認する

元画像のパスはget_attached_file()で取得できます。生成済みサイズのファイル名は元画像と同じディレクトリを基準にし、is_file()で存在を確認します。

function example_inspect_attachment_image_files( $attachment_id ) {
	$metadata = wp_get_attachment_metadata( $attachment_id );

	if ( ! is_array( $metadata ) ) {
		return false;
	}

	$original_file = get_attached_file( $attachment_id );

	if ( ! $original_file ) {
		return false;
	}

	$files = array(
		'full' => array(
			'path'   => $original_file,
			'exists' => is_file( $original_file ),
		),
	);

	if ( ! empty( $metadata['sizes'] ) && is_array( $metadata['sizes'] ) ) {
		$directory = trailingslashit( dirname( $original_file ) );

		foreach ( $metadata['sizes'] as $size_name => $size_data ) {
			if ( empty( $size_data['file'] ) ) {
				continue;
			}

			$size_file = $directory . wp_basename( $size_data['file'] );
			$files[ $size_name ] = array(
				'path'   => $size_file,
				'exists' => is_file( $size_file ),
			);
		}
	}

	return $files;
}

この関数が返すexistsは、ローカルのファイルシステム上に通常ファイルがあるかを示します。画像URLが外部から取得できるか、Webサーバーが読み取りを許可するか、HTMLが正しいサイズを選ぶかは別に確認します。

不足している対象を確定してから復旧方法を選ぶ

調査結果は、少なくとも次の三つに分かれます。

メタデータ 実ファイル 次に調べる対象
ある ある テンプレートが選ぶサイズ名、生成URL、読み取り権限
ある ない uploadsの復元範囲、削除記録、画像生成処理
ない ある 添付ID、_wp_attachment_metadataの保存処理、復元したデータベース

元画像まで失われている状態と、中間画像だけが足りない状態では、復旧方法が違います。sizesが空だからという理由だけで、添付ファイル投稿を削除してアップロードし直してはいけません。まず元画像、メタデータ、中間画像のどこが不足しているかを確定します。

バックアップも、データベースだけでは画像ファイルを戻せません。uploadsとデータベースを同じ復元時点で管理し、復元後に一つの添付IDでメタデータと実ファイルを照合してください。

戻る