やっかいなサーバで「imagettfbbox」が使えない

あー、もう厄介なサーバはほんとやだ。

Call to undefined function imagettfbbox() …

GD関数は使えるんだけど、imagettfbbox関数が使えない。何かコンパイルオプションが足りてないんだっけ、と調べてみたらfreetypeが組み込まれていない。phpinfoのGD欄に「FreeType Support」の記載がないのだ。

関数が使えなければ始まらないので、サーバ会社に依頼してみた。使えなければ、もう終わりだな。

UTF-16LEで改行あたりが勝手に変換される

MD5ハッシュ値を返すmd5関数とmd5_file関数。前者は引数としてハッシュ化したい文字列を受け、後者は引数としてハッシュ化したいファイルのパスを受ける。ここまではマニュアル通り。

とある仕事で、「UTF-16LE」のファイルをPHPで取り扱う際に、うまくいかない問題が生じている。「UTF-16LE」を使うのには理由があって、ファイルをエクセルでそのまま扱いたいからだ(エクセルで編集してアップロード、ダウンロードしてエクセルで編集)。

開発環境で用意したスクリプトを本番環境に移設してテストするのだが、これがなんともうまく動作しない。いろいろ探ったのだが、どうもそのサーバでは「UTF-16LE」で記述されたファイルをPHPで読み込むと、どういうわけか改行コード付近を勝手に変換しているように見受けられる。単にfile_get_contentsしているだけなのに!。

自分で借りているレンタルサーバ、VPS、自分のMacで、file_get_contentsした値をbin2hexして出力してみると、そのサーバでだけ値が異なってしまう。ひょっとしてサーバへの転送の時点で何らかの変換がかかっているのかも、と思ってサーバにあるファイルに対してmd5_file関数でハッシュを取るとそれは全て同じ値が返ってくる。つまりテストしているファイルは同じファイルであることに間違いはない。

そして冒頭のmd5。file_get_contentsした値に対してmd5すると当然md5_fileとおなじになるはずなのに・・・そのサーバだけ違う値。つまりmd5した結果とmd5_fileした結果が異なる値になっている。

いろいろ調べて、文字コードが「UTF-8」の場合は、そのサーバでも事象が発生しなかった。さーどうしようか。サーバ会社に文句を言えばいいのだが、たいていは「プログラムに問題があるんじゃないですか」で終わってしまう(既に別件で適当な嘘を疲れているのでこのサーバ会社は一切信用出来ない)。PHP5.2系の問題である可能性も捨て切れない。もうちょっと悩んでからクライアントに相談することにする。

PHPでファイルが壊れる時に

とある仕事でデータをファイルに書いて保存する処理を組み込んだ。

ある時、「ファイルが壊れるんだけど」という連絡をいただき、いろいろ調べたのだが結局原因がわからずじまいだった。もちろんflockしてるし、ファイルバッファも0にしている。アクセス数が極端に多いわけでもないので、偶発的に壊れるのであればわかるけれど、時々壊れるというのだから原因がわからない。で、調べてみた。

どうやらマルチスレッド環境にflockが対応していないということに起因するかもしれない、ということがわかった。apacheの設定を調べてみなくてはいけない。preforkならOK、それ以外だとアウト、という感じでいいんだろうか。

どうしてもダメならSQLiteに変更するか。

fgetcsvで文字が消える

fgetcsvはシフトJISで正しく動作しない、というのは前に確認したことがあった(頭の片隅に残っていた)。再度調べたらダブルクォーテーションで値が囲われていない場合にエラーが出るらしい(自分で確認すればいいのだが、そもそもシフトJISのまま使うことがないので確認しない)。これはエクセルからエクスポートした際に問題になる。

しかし、じゃぁUTF-8やEUC-JPで問題が発生しないか、というとやっぱり発生する。サーバのロケールの設定に依存するため、使用する言語とロケールが合致していない場合、やはりダブルクォーテーションで囲われていない値があれば文字の欠落が発生する。

使用する言語が決まっているのであれば問題ない。setlocale関数で指定してやればいいから。

使用する言語が決まっていない場合(どんな言語で与えられるかわからない場合)、fgetcsvは使えない、という結論だ。

あー、やだやだ。

前後のクォーテーションを取り除く

文字列の前後にダブルクォーテーションやシングルクォーテーションがくっついた状態で文字列が渡されることがある。そんな時に不要な前後の文字列を取り除く便利な方法を見つけた。

$moji=trim($moji,”\x22 \x27″);

trim関数に第2引数を与えて、取り除きたい文字列を指定すればよい。簡単。


守谷市(まちの情報ポータル) 無料アンケートレンタルjpForm.net