ウェブブラウザで画像ファイルをダウンロードする場合、URL は
というように、末尾がそのファイル名になっていることが多いと思います。
これは、「ウェブサーバーに置いてある画像ファイルへのパスが、そのままURLになっている」という一番シンプルなやり方です。
(実はそう装っているだけで、複雑な処理をして画像ファイルを返している可能性もありますが)
それに対して、以下のようなURLで画像ファイルを返している場合があります。
こういう場合は、「ウェブサーバー側で何か特別な処理をしているはずだ」と考えるべきでしょう。
いろいろやり方はあると思いますが、本記事では PHP によるコード例を1つ紹介します。
PHPを使って画像を返す方法
先程のURLであれば、以下のようなディレクトリ・ファイルを用意します。
- ドキュメントルートに
foo
という名前のディレクトリを作成する。 - その下に
bar
という名前のディレクトリを作成する。 - 更にその下に、
index.php
という名前のファイルを作成する。
これに加えて、ドキュメントルート外に baz.png
という名前の画像ファイルがあるとします。ブラウザにはこの画像を間接的に返すことになります。
また、URL 内のパス部分に /foo/bar/ と指定してアクセスした場合、bar ディレクトリ直下にある index.php
が実行されます(PHPが使えるウェブサーバーであれば、普通はこうなっています)。
ディレクトリ構成はこんな感じです。
とあるディレクトリ
├ ドキュメントルート
│ └ foo/
│ └ bar/
│ └ index.php
└ images/
└ baz.png
index.php
には以下のコードを記述します。
<?php
$data = file_get_contents('../../../images/baz.png'); // 元画像をデータとして取得
header('Content-Type: image/png'); // コンテンツの種類を返す
header('Content-Length: ' . strlen($data)); // コンテンツの長さを返す
echo $data; // 画像データを出力する
各行のコメントに、その行でやっている意味を書きました。
補足情報
ここで使っている PHP関数のマニュアルページリンクを貼っておきます。
同じく HTTPレスポンスヘッダについては以下を参照してください。
このやり方であれば、元となる画像ファイルをドキュメントルート以下に置く必要がありませんし(画像ファイルがインターネットに晒されずに済みます)、返す画像を変更したい場合に URL を変更する必要がありません。わざわざコードを書いているだけあってそのあたりの柔軟性がアップしています。
少しURLは違っていますが、このコードを実際に試してみた際のレスポンスヘッダが以下になります( Chrome ブラウザの開発者ツールで見ています)。
おまけ
ついでに、header()
関数の下に次のコードを追加すると、ブラウザにダウンロードを指示することができます。その際のファイル名デフォルト値は「foobar.png」になります。
header('Content-Disposition: attachment; filename="foobar.png"');
参照