hyperdb.work

こいつ何者?

最近、自分専用のスピードダイアルのようなサイトを作ろうかと思っていろいろと準備を始めました。

その中でサイトのURLを登録する際にOGPで画像のURLを取得してキャッシュしておくのが良いかなと思ったわけですが、動的にOGP画像を生成しているようなサイトではURLに画像ファイルの拡張子がついているわけでもなく、「はて、こいつ何者?」ってことになってしまったわけです(まあ、そういう場合はたいていPNGだとは思いますが)。ということでfile_get_contentsで取得した画像が何者なのかを知るすべを考えてみることにしました。

マジックナンバーを使う

マジックナンバーとは、ファイル形式を識別するためにファイルの先頭に記述されている数バイトのデータのことです。 file_get_contents()で取得したデータから最初の数バイトを読み取り、既知のマジックナンバーと比較することで、ファイル形式を判定できます。
~ Gemini Flash 2.5

昔何かの記事で読んだJPEG画像は先頭がFF D8 FFで始まるみたいなことが使えるのではないかと考えました。OGP画像として返されるわけですから画像データであることは(たぶん)間違いないわけで先頭の何文字かで判定できるのであればもっけの幸いというところでしょうか。

$_image = file_get_contents($url);
$_image_header = substr($_image, 0, 8);

$_image_ext = "png";
if (strpos($_image_header, "\xFF\xD8\xFF") === 0) {
    $_image_ext = "jpeg";
}

簡単すぎる例ですが、こんな感じで拡張子を決めてあげれば「こいつ何者」問題は解決するのではないでしょうか。

マジックナンバーの例

マジックナンバーの例をChatGPTに聞いてみました。

フォーマットマジックナンバー(16進)説明
JPEGFF D8 FFJPEGファイルは常に 0xFFD8 で始まり、0xFFD9 で終わります。
PNG89 50 4E 47 0D 0A 1A 0AASCIIで ‰PNG、PNG専用の署名。
GIF87a47 49 46 38 37 61ASCIIで GIF87a。古いGIFフォーマット。
GIF89a47 49 46 38 39 61ASCIIで GIF89a。透過などに対応。
BMP42 4DASCIIで BM。Windows Bitmap形式。
WebP52 49 46 46(+ offsetで WEBPRIFF形式(RIFFxxxxWEBP)を使っている。先頭4バイトは RIFF。8バイト目から WEBP
TIFF (LE)49 49 2A 00リトルエンディアン(Intel)形式のTIFF。
TIFF (BE)4D 4D 00 2Aビッグエンディアン(Motorola)形式のTIFF。
ICO00 00 01 00Windowsアイコン形式。
公開日時:2025/08/06 19:30:21 更新日時:2025/08/25 18:02:35