雑感
こいつ何者?
最近、自分専用のスピードダイアルのようなサイトを作ろうかと思っていろいろと準備を始めました。
その中でサイトの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進) | 説明 |
---|---|---|
JPEG | FF D8 FF | JPEGファイルは常に 0xFFD8 で始まり、0xFFD9 で終わります。 |
PNG | 89 50 4E 47 0D 0A 1A 0A | ASCIIで ‰PNG 、PNG専用の署名。 |
GIF87a | 47 49 46 38 37 61 | ASCIIで GIF87a 。古いGIFフォーマット。 |
GIF89a | 47 49 46 38 39 61 | ASCIIで GIF89a 。透過などに対応。 |
BMP | 42 4D | ASCIIで BM 。Windows Bitmap形式。 |
WebP | 52 49 46 46 (+ offsetで WEBP ) | RIFF形式(RIFFxxxxWEBP )を使っている。先頭4バイトは RIFF 。8バイト目から WEBP 。 |
TIFF (LE) | 49 49 2A 00 | リトルエンディアン(Intel)形式のTIFF。 |
TIFF (BE) | 4D 4D 00 2A | ビッグエンディアン(Motorola)形式のTIFF。 |
ICO | 00 00 01 00 | Windowsアイコン形式。 |