さぁ、今回は3日で通算8時間ほどハマったPHP の GD ライブラリ を使おうとした時の
事柄を書いて置こう。
結果から言うと、ブラウザが識別できるヘッダー情報を付加して送るPHPの関数である
header 関数は、header 関数でMIME を設定しただけではブラウザ 側がしっかり認識できないと言うことです。
すぐに対象方法が知りたい場合はかなり読み飛ばして
<対処方法>を読めば早いです。
またそれ以前にPHP のGD ライブラリで画像を吐き出させようとheader 関数を呼ぶと
その時点でheader が既に呼び出されてエラーを出してしまう場合は、
php.ini の設定でアウトプットのバッファー設定がオフだと何かPHP関連のファイルを
ブラウザに出力する記述があった場合に即座にheader をPHP が吐き出してしまう様です。
なのでoutput_buffering = off
に成っているのならば、
output_buffering = 4096
などに変更しましょう、
それでなければほとんど、header 関数自体が使えないと
思った方が良いかもしれません。
header 関数でMIME を設定しただけではブラウザ 側がしっかり認識できない方の理由はどうも、
ブラウザが直接ヘッダーを確認する前に、どうもWebサーバ が間に入り、
その情報を操作してしまっているみたいです。
私の場合は
XAMPP などは使わず、WAMP 環境を個別にインストールと設定を行い、
環境を整えてきました。
もしかすると私が使ったことが無いXAMPP などを使っている人は、
設定がもうされていたりして困らない事なのかもしれないですが、そこは未確認です。
--- 知ってたら飛ばしていい所 ---
ま、でも知らない人にまずGD ライブラリ とは何か?
と言うと、PHP スクリプトを用いて文字や図形をWBMP やGIF 、PNG、JPEG などの画像情報を
作り、それをWeb サーバ上の溶媒に保存したり、Webサーバ に保存しないでメモリ上にある
画像情報 と、ブラウザ がどんな情報か解釈できるヘッダー情報 を追加して、
それをApache などのWebサーバ を通してブラウザに送り、
ブラウザ側に表示できるという一風変わった、しかし優れた物である。
多分、よく使われていると思われる場面というのは、
新規にフリーメールなどや何処かの会員に登録する時に、
不正にアカウントを取得されない様に画像に数字や文字が書かれ、
それを誤り無く入力しなければいけない場面で使われていると思う。
それでは簡単な例を載せようと思いましたが、
基本的にGD ライブラリのImage 関数の例にある事柄をしようとすると
それが出来ないので、その例はそのImage 関数のマニュアルに書いてあるので、
割愛し、重要なheader 関数の事柄だけを書いてみます。
imagegif 関数の場合
header('Content-Type: image/gif');
imagepng 関数の場合
header('Content-Type: image/png');
imagejpeg 関数の場合
header('Content-Type: image/jpeg');
ここで定義しているのでブラウザ側はこれで動く様に思える、
しかし実は
Apache でMIME のタイプが指定されていなければ、ブラウザで判断出来ない様だ。
それが分かったのは、レンタルサーバに上げると自身の書いたPHPスクリプトは動く、
phpinfo 関数を使ってWindows 環境とLinux 環境の違いはあれ、ほぼ一緒にしているのに
サーバに上げた方は正常に画像がブラウザで表示されるのに、ローカル側では
ブラウザで表示されない、そこで気がついたのだった。
<対処方法>
ここで重要な対象方法ですが、とても簡単です。
Apache の設定ファイルにPHP で自分で使いたいMIME タイプを
「httpd.conf」の中に①AddType でMIME を個別に指定するか、
それとも、実はApache を普通にインストールすると付随している
②設定ファイル(mime.types)を読み込む記述をすると、
MIME タイプの設定が完了します。(勿論Apache は再起動しなければいけません)
このどちらかの方法でMIME タイプを読み込めると言うことです。
もし、「mime.types」のファイルを使わないならば、
①の方法のApache の設定ファイルの「httpd.conf」の中に
AddType image/jpeg .jpeg .jpg .jpe
と書けばいいのです。
設定ファイル「mime.types」は、中の定義で基本的なMIME タイプの設定がかなりの量が成されています、
これを基本ベースとして足らないMIME の付け加えや修正を行えば便利だと思います。
②の「mime.types」を読み込む設定を「httpd.conf」の中に書くには、
TypesConfig conf/mime.types
と1行書くだけです。
これだけの事が分かるまでに私はPHPの挙動の方を疑って結構悩みました。
さて、「mime.types」のファイルで例えば
JPG ですが、どの様に定義されているかを見ると、
image/jpeg jpeg jpg jpe
と書いてありました。
このどちらかを書けば、情報は送信されていてサイズもあるのに表示されないという
悩ましい事態から抜け出すことが出来ると思います。
最後に注意点というか論点ですが、「mime.types」のファイルを用いる場合に、
自身が使いたいヘッダー情報があるかどうかを確認した方が良いかもしれません。
使いたいMIME タイプが定義してあるかどうかの設定なのですから。
- - - - - -
追伸:
もしもPNGファイルの画像を出力するスクリプトをPHPで書くならば、
そのスクリプトの保存形式をUTF-8の場合は必ずBOM無しにしなければいけません。
imagefttext やimagettftext 関数で画像を使う場合、
保存形式をUTF-8(BOMあり)ではなくUTF-8(BOMなし)にして保存しなければ、
画像データの先頭まで、ファイル形式の構造情報が3バイト付加されてしまうので、
画像データとして用いることができなくなるので注意が必要です。
れこは関数が画像をファイルとして出力する機能が衝突するからでしょうか?
不可思議な仕様ですが、PHPの画像生成関数は現在BOMに依存している様です。
UTF-16だと2バイトのBOMが付き、それは意味があるそうですが、
UTF-8でのBOMは実際には無意味なものらしいです。
詳しくは、BOM をどうぞ。
長い個人的なメモなのか説明なのか毎回分かりませんが、以上ですw
コメント一覧