プログラミング言語や環境設定を中心としたパソコン関連の技術メモです。
主にシステム開発中に調べたことをメモしています。TIPS的な位置付けで、気が向いたときにちまちま更新していきます。
PHP経由で画像ファイルを表示する
結論から書けば

1.「画像ですよ~」なヘッダを送る
header('Content-Type: image/png');

2.画像の中身を送る
readfile('img/img01.png');

をPHP側でやればOKです。

実際に見た方が分かりやすいと思うのでサンプルコードφ(--)

■img.php
<?php
    try {
        //画像の情報(ファイルパスとContent-Typeの配列)
        $imgArray = array('img/img01.png', 'image/png');

        if (file_exists($imgArray[0])) {    //画像存在チェック
            //画像表示
            header('Content-Type: ' . $imgArray[1]);
            readfile($imgArray[0]);

        }else{
            //画像が無い場合はException
            throw new Exception;
        }
    } catch(Exception $e){
        //エラー画像表示
        header('Content-Type: image/png');

        //readfile('img/err.png');
        print base64_decode('iVBORw0KGgoAAAANSUhEUgAAAFAAAABQCAYAAACOEfKtAAAABGdBTUEAAK/INwWK6QAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIZSURBVHhe7dsxcptAGIbhn5wFucjkBMsJZPdp0+FSaty5TJcGSrtLmz7yCcwJMiki7rJZdjcxtjR4zIdUJO8zwxix8o55xUIjFz4wzPYu/8RMBBQRUERAEQFFBBQRUERAEQFFBBQRUERAEQFFBBQRUERAEQFFBBQRUERAEQFFBBQRUERAEQFFBBQRUERAEQFFBBQRUERA0ckC9m1lRVGMtsraPg9ab22VjlfDwYfr9J6qDSNTY/m3D+Yu7PohD0avz7GY4Ruqy9r7xtnwrdcjm/PNfuI9rgkjU2Pe7+ojY3lzafJgeo4lLR9wV+c/uPa7fGh8QukkX74emxjbN97Fuc3XT5OHwy4eO/YBHc6/rMWXcP/rR967t8u/S2xl2y4d7X7u084M/fdvFqdxjd2s46Go3NxaHfc6E6af5XQPkXCS4bMfrvDn293ozP8BiwcsLz6knW5rn56eGtFw839+s3+b8uqjhSUc5/4ymqdvP4frfeDs/SrunM3yV+D6xsL9J+q2q7yE07b6s47nKjd2m9aq3V8ezuuar7Yp4+7ZnGAJl7Z59BZu7Pn1yIt71xzru+Nzh4eKPZ67XsA/2ohO9xD5TxBQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQYvYbxldXOMXATVUAAAAASUVORK5CYII=');
    }

メインとなる部分は

header('Content-Type: ' . $imgArray[1]);
readfile($imgArray[0]);

です。
ヘッダを出力して中身を出力しています。
今回はreadfile()一発でやっていますが、file_get_contents()からのprint()でも何でもお好きにどうぞ。

Content-Typeは「image/png」「image/jpeg」「image/gif」など画像の種類によって変わるので、
画像ファイルへのパスと一緒に配列として管理しています。
例えばpng画像しか出さないのであれば

header('Content-Type: image/png');

のように固定で書いてしまっても構いません。

    } catch(Exception $e){
        //エラー画像表示
        header('Content-Type: image/png');

        //readfile('img/err.png');
        print base64_decode('iVBORw0KGgoAAAANSUhEUgAAAFAAAABQCAYAAACOEfKtAAAABGdBTUEAAK/INwWK6QAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIZSURBVHhe7dsxcptAGIbhn5wFucjkBMsJZPdp0+FSaty5TJcGSrtLmz7yCcwJMiki7rJZdjcxtjR4zIdUJO8zwxix8o55xUIjFz4wzPYu/8RMBBQRUERAEQFFBBQRUERAEQFFBBQRUERAEQFFBBQRUERAEQFFBBQRUERAEQFFBBQRUERAEQFFBBQRUERAEQFFBBQRUERA0ckC9m1lRVGMtsraPg9ab22VjlfDwYfr9J6qDSNTY/m3D+Yu7PohD0avz7GY4Ruqy9r7xtnwrdcjm/PNfuI9rgkjU2Pe7+ojY3lzafJgeo4lLR9wV+c/uPa7fGh8QukkX74emxjbN97Fuc3XT5OHwy4eO/YBHc6/rMWXcP/rR967t8u/S2xl2y4d7X7u084M/fdvFqdxjd2s46Go3NxaHfc6E6af5XQPkXCS4bMfrvDn293ozP8BiwcsLz6knW5rn56eGtFw839+s3+b8uqjhSUc5/4ymqdvP4frfeDs/SrunM3yV+D6xsL9J+q2q7yE07b6s47nKjd2m9aq3V8ezuuar7Yp4+7ZnGAJl7Z59BZu7Pn1yIt71xzru+Nzh4eKPZ67XsA/2ohO9xD5TxBQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQYvYbxldXOMXATVUAAAAASUVORK5CYII=');
    }

の部分はエラー発生時の処理です。
呼出元では

<img src="img.php">

のように記述することを想定していますので、
エラー発生時も画像を返却するようにしています。
ちなみに

print base64_decode('iVBORw0KGgoAAAANSUhEUgAAAFAAAABQCAYAAACOEfKtAAAABGdBTUEAAK/INwWK6QAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIZSURBVHhe7dsxcptAGIbhn5wFucjkBMsJZPdp0+FSaty5TJcGSrtLmz7yCcwJMiki7rJZdjcxtjR4zIdUJO8zwxix8o55xUIjFz4wzPYu/8RMBBQRUERAEQFFBBQRUERAEQFFBBQRUERAEQFFBBQRUERAEQFFBBQRUERAEQFFBBQRUERAEQFFBBQRUERAEQFFBBQRUERA0ckC9m1lRVGMtsraPg9ab22VjlfDwYfr9J6qDSNTY/m3D+Yu7PohD0avz7GY4Ruqy9r7xtnwrdcjm/PNfuI9rgkjU2Pe7+ojY3lzafJgeo4lLR9wV+c/uPa7fGh8QukkX74emxjbN97Fuc3XT5OHwy4eO/YBHc6/rMWXcP/rR967t8u/S2xl2y4d7X7u084M/fdvFqdxjd2s46Go3NxaHfc6E6af5XQPkXCS4bMfrvDn293ozP8BiwcsLz6knW5rn56eGtFw839+s3+b8uqjhSUc5/4ymqdvP4frfeDs/SrunM3yV+D6xsL9J+q2q7yE07b6s47nKjd2m9aq3V8ezuuar7Yp4+7ZnGAJl7Z59BZu7Pn1yIt71xzru+Nzh4eKPZ67XsA/2ohO9xD5TxBQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQYvYbxldXOMXATVUAAAAASUVORK5CYII=');

の部分については、画像「img/err.png」をbase64_encode()した文字列をあらかじめ用意しておいて
そいつをbase64_decode()して(画像に戻して)送り返しています。
「Data URI Scheme」関連のちょっとした応用ですね。
「img/err.png」が存在しませんよエラーを回避するための処置です。

サンプルコードの説明としてはそんな感じです。

「画像をプログラム経由で呼び出して何か良いことあるの?」と思うかも知れませんが、
パッと思いつくメリットは

1.実際の画像ファイル名を隠蔽できる
2.気休めだけど閲覧制限をかけられる


でしょうか。

「1.実際の画像ファイル名を隠蔽できる」については、
例えば、こんな感じのコードにしますφ(--)

<?php
    try {
        //ファイルパスとContent-Typeの配列
        $imgArray = array('a' => array('img/img01.png', 'image/png'),
                        'b' => array('img/img02.gif', 'image/gif'),
                        'c' => array('img/img03.jpeg', 'image/jpeg'),
                    );


        //パラメータ取得
        $key = $_GET['key'];

        if(array_key_exists($key , $imgArray) === false){
            //パラメータがおかしい
            throw new Exception;
        }


        if (file_exists($imgArray[$key][0])) {
            //画像表示
            header('Content-Type: ' . $imgArray[$key][1]);
            readfile($imgArray[$key][0]);
        }else{
            //指定画像が無い
            throw new Exception;
        }
    } catch(Exception $e){
        //エラー画像表示
        header('Content-Type: image/png');

        //readfile('img/err.png');
        print base64_decode('iVBORw0KGgoAAAANSUhEUgAAAFAAAABQCAYAAACOEfKtAAAABGdBTUEAAK/INwWK6QAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIZSURBVHhe7dsxcptAGIbhn5wFucjkBMsJZPdp0+FSaty5TJcGSrtLmz7yCcwJMiki7rJZdjcxtjR4zIdUJO8zwxix8o55xUIjFz4wzPYu/8RMBBQRUERAEQFFBBQRUERAEQFFBBQRUERAEQFFBBQRUERAEQFFBBQRUERAEQFFBBQRUERAEQFFBBQRUERAEQFFBBQRUERA0ckC9m1lRVGMtsraPg9ab22VjlfDwYfr9J6qDSNTY/m3D+Yu7PohD0avz7GY4Ruqy9r7xtnwrdcjm/PNfuI9rgkjU2Pe7+ojY3lzafJgeo4lLR9wV+c/uPa7fGh8QukkX74emxjbN97Fuc3XT5OHwy4eO/YBHc6/rMWXcP/rR967t8u/S2xl2y4d7X7u084M/fdvFqdxjd2s46Go3NxaHfc6E6af5XQPkXCS4bMfrvDn293ozP8BiwcsLz6knW5rn56eGtFw839+s3+b8uqjhSUc5/4ymqdvP4frfeDs/SrunM3yV+D6xsL9J+q2q7yE07b6s47nKjd2m9aq3V8ezuuar7Yp4+7ZnGAJl7Z59BZu7Pn1yIt71xzru+Nzh4eKPZ67XsA/2ohO9xD5TxBQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQYvYbxldXOMXATVUAAAAASUVORK5CYII=');

    }

呼出元ではこんな感じで指定しますφ(--)

<img src="img.php?key=a">
<img src="img.php?key=b">
<img src="img.php?key=c">

これで実際の画像ファイル名「img01.png」「img02.gif」「img03.jpeg」を隠蔽できます。
画像ファイルの置いてある場所「img/」も併せて隠蔽されるので、
セキュリティ的にちょっとはマシになるんじゃないですかね。

「2.気休めだけど閲覧制限をかけられる」については、
例えばこんな感じでログイン済みチェックを入れるとかですねφ(--)

<?php
    try {

        if($_SESSION['loginFlg'] === false){
            //未ログイン
            throw new Exception;
        }


        //画像の情報(ファイルパスとContent-Typeの配列)
        $imgArray = array('img/img01.png', 'image/png');

        if (file_exists($imgArray[0])) {
            //画像表示
            header('Content-Type: ' . $imgArray[1]);
            readfile($imgArray[0]);
        }else{
            //画像が無い場合
            throw new Exception;
        }
    } catch(Exception $e){
        //エラー画像表示
        header('Content-Type: image/png');

        //readfile('img/err.png');
        print base64_decode('iVBORw0KGgoAAAANSUhEUgAAAFAAAABQCAYAAACOEfKtAAAABGdBTUEAAK/INwWK6QAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIZSURBVHhe7dsxcptAGIbhn5wFucjkBMsJZPdp0+FSaty5TJcGSrtLmz7yCcwJMiki7rJZdjcxtjR4zIdUJO8zwxix8o55xUIjFz4wzPYu/8RMBBQRUERAEQFFBBQRUERAEQFFBBQRUERAEQFFBBQRUERAEQFFBBQRUERAEQFFBBQRUERAEQFFBBQRUERAEQFFBBQRUERA0ckC9m1lRVGMtsraPg9ab22VjlfDwYfr9J6qDSNTY/m3D+Yu7PohD0avz7GY4Ruqy9r7xtnwrdcjm/PNfuI9rgkjU2Pe7+ojY3lzafJgeo4lLR9wV+c/uPa7fGh8QukkX74emxjbN97Fuc3XT5OHwy4eO/YBHc6/rMWXcP/rR967t8u/S2xl2y4d7X7u084M/fdvFqdxjd2s46Go3NxaHfc6E6af5XQPkXCS4bMfrvDn293ozP8BiwcsLz6knW5rn56eGtFw839+s3+b8uqjhSUc5/4ymqdvP4frfeDs/SrunM3yV+D6xsL9J+q2q7yE07b6s47nKjd2m9aq3V8ezuuar7Yp4+7ZnGAJl7Z59BZu7Pn1yIt71xzru+Nzh4eKPZ67XsA/2ohO9xD5TxBQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQREARAUUEFBFQYvYbxldXOMXATVUAAAAASUVORK5CYII=');
    }

気休め以上の効果は無いでしょうが、気休めとしては中々有効なんじゃないでしょうか。
ログインチェックで未ログイン者には表示しない以外にも、
ユーザエージェントやIPアドレスで判定して、ボットや収集ツールには表示しない等の応用も利きそうです。

そんな感じ\(--)/
スポンサーリンク
 
このエントリーをはてなブックマークに追加 

category:● PHP  thema:システム開発 - genre:コンピュータ  Posted by ササキマコト 

  関連記事