Apache の ModRewrite の機能を使って、PHP ファイルを画像ファイルとして読み込むといったことができるが、その際に気をつけないとハマる事がある。
ファイルの配置
例えば、.htaccess
を以下のようにして、donation.png
画像へのアクセスを donation.php
にする。
.htaccess
1 2 |
RewriteEngine On RewriteRule donation.png donation.php |
donation.png
は存在しない。なので、実際に読み込ませる画像を用意する。ここでは名称を dummy.png
としている。
そして、同階層に donation.php
と dummy.png
ファイルを置く。donation.pnp
は以下のように記述し、dummy.png
画像をその都度読み込んでレンダリングさせるようにする。donation.pnp
は以下のように記述し、dummy.png
画像をその都度読み込んでレンダリングさせるようにする。
donation.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
<?php showPNG( dirname( __FILE__ ) . "/dummy.png" ); function showPNG( $sPNGPath ) { $im = getPNG( $sPNGPath ); // For transparency (Alpha blending) imagealphablending($im, true); imagesavealpha($im, true); // Set header header('Content-Type: image/png'); // Output image imagepng($im); // Unload image imagedestroy($im); flush(); } /** * Gets png image resource handler from a given file path. */ function getPNG( $imgname ) { // Attempt to open $im = @imagecreatefrompng( $imgname ); // See if it failed if( ! $im ) { // Create a blank image $im = imagecreatetruecolor( 150, 30 ); $bgc = imagecolorallocate( $im, 255, 255, 255 ); $tc = imagecolorallocate( $im, 0, 0, 0 ); imagefilledrectangle( $im, 0, 0, 150, 30, $bgc ); // Output an error message imagestring( $im, 1, 5, 5, 'Error loading ' . $imgname, $tc ); } return $im; } |
これでブラウザでアクセスすると、普通の画像として表示される。このテクニック使えば、画像をランダムに表示させたり、任意のコードを実行させたりすることができる。
落とし穴
ここで、例えば、画像を差し替えようとして、仮に、donation.png.bak
ファイルをバックアップとして、同階層に配置するとどうなるか。
Not Found が表示される。これを知らずに、Apache に問題があるのではないか、サーバーの設定に問題があるのではないか、.htaccess
の記述に誤りはないか、ファイルのパーミッションはどうなっているのか、などとトラブルシューティングしていると、大変な時間を浪費することになる。
対処方法としては、バックアップファイル名を donation.bak.png
など、donation.png
にマッチしないようにして回避できる。またそもそもそのようなファイルを置かないとか。
imagecreatefrompng()
は全てのPNG形式に対応してない?
少しずれるが、上記のコードでは、PHP 関数の imagecreatefrompng()
で png 画像を読み込むのだけど、これ、Web 上で落としてきた画像をそのまま放り込むと false
を返して正常に読み込んでくれない時がある。なので、画像処理ソフトで保存し直さないといけなかったりする事がある。
軽く調べてみると、原因は bit 数がどうのこうの。ビット数変えて保存し直して読み込ませてみたけれど、特に問題なし。んー、よくわからん。