FC2ブログはソースの直接入力がやりずらくなった
ブログにプログラムコードなんかを貼りつけるときはHTMLを直接編集できるモードで記事を書いた方が楽なのだがFC2ブログではそれがやりづらくなった。他に行くしかないな。
TokyoTyrantとLuaでハマった記録
同じことではまらないために書いておく。
TokyoTyrantサーバーで今日の日付と昨日の日付を取得するluaスクリプトを実行するようにした。
function get_date() local today = os.date("%y%m%d") local yesterday = os.date("%y%m%d", os.time()-86400) end PHPで顔認識を試してみた
写真から人間の顔を検出してその部分を緑色の四角形で囲むスクリプトを書いて遊びました。
環境はCentOS5.2です。
顔認識の処理はOpenCVに依存してますのでまずそれを入れます。
yum -y install opencv
次に、PHPで顔検出を参考にOpenCVをPHPから使えるようにするextensionを入れます。
そして、それを使って実際に顔検出してみたスクリプトがこちら
<?php
$pic = 'aoi.jpg';
$cascade = '/usr/share/opencv/haarcascades/haarcascade_frontalface_alt.xml';
$faces = face_detect($pic, $cascade);
var_dump($faces);
$img = imagecreatefromjpeg($pic);
$color = imagecolorallocate($img, 0, 255, 0);
foreach($faces as $face){
$x1 = $face['x'];
$y1 = $face['y'];
$x2 = $x1 + $face['width'];
$y2 = $y1 + $face['height'];
imagerectangle($img, $x1, $y1, $x2, $y2, $color);
}
imagejpeg($img, 'aoi_face.jpg');
?>
ちゃんと写真のなかに2人いたら2人分の顔を検出できました。
いや〜、何でも便利なものが転がってるもんだなぁ。
PHPから静的な画像ファイルを効率的に出力する方法
サーバー上の静的なコンテンツをPHPなどの動的なスクリプトから出力したときがたまに有ります。
例えばログインしているユーザーにだけ画像を見せたい場合などです。
こういう時、一番簡単な方法は
if($logged_in){
$filename = 'hoge.gif';
header('Content-Length: ' . filesize($filename));
header('Content-Disposition: attachment; filename='.basename($filename));
readfile($filename);
}とする事です。
若しくは
if($logged_in){
$filename = 'hoge.gif';
header('Content-Length: ' . filesize($filename));
header('Content-Disposition: attachment; filename='.basename($filename));
$fp = fopen($filename, 'rb');
fpassthru($fp);
fclose($fp);
}というのも同様です。これらは簡単に実装できますし、そんなに負荷のかからない環境でなら十分実用に耐えます。
ですが、これらは静的ファイルのデータを一旦PHPがバッファに蓄えてから出力するので余計なメモリを食ってしまいます。
実際に上のどちらかのコードの下に
$buffer = ob_get_contents(); //PHPのアウトプットバッファ内のデータを取得して変数に格納
ob_end_clean(); //アウトプットバッファの中身を空っぽにする
echo $buffer; //バッファの中身を出力
というコードを書いて実行するとhoge.gifの内容が出力され、バッファに画像データが読み込まれていることが確認できます。
※アウトプットバッファのサイズより大きなサイズの画像を扱う場合は挙動が異なります。
また、何度も同じコンテンツを出力する場合、そのデータはメモリなどの高速なストレージにキャッシュして置きたいものです。
そういう仕組みをPHPとmemcachedやAPCを利用して組むことも可能ですが、Apacheには既にそういう機能がありますのでそれを使うのも手です。
今回は静的ファイルの出力とキャッシングをApacheに委ねてパフォーマンスを向上を狙いたいと思います。
まず、Apacheに静的ファイルの出力を任せるためにmod_xsendfileというモジュールを導入します。
CentOS5の場合は
yum -y install httpd-devel
wget http://tn123.ath.cx/mod_xsendfile/mod_xsendfile-0.9.tar.gz
tar xfz mod_xsendfile-0.9.tar.gz
cd mod_xsendfile-0.9
apxs -cia mod_xsendfile.c
これでmod_xsendfile.soが作られて適切な場所に配置され、httpd.confの中にそのモジュールをロードする設定まで追加されている筈です。
環境によってはsoファイルの配置やhttpd.confの編集は自分でやる必要があるかもしれませんので、後述の設定にしたがって編集してください。
途中でエラーが出てしまった場合はhttp://blog.s2factory.co.jp/yoshizu/2008/09/leopard-mod-xsendfile.htmlを参考にsoを作ると解決するかもしれません。
WindowsXPの場合はhttp://www.apachelounge.com/download/から
mod_xsendfile-0.9-w32.zipをダウンロード、解凍してできたmod_xsendfile.soを
Apacheのインストールディレクトリの中のmodulesフォルダに移動します。
※上のCentOS用のファイルがあるサイトにはWindows用のバイナリも置いてありますが、私の環境では動きませんでした。
CentOS5、WindowsXP両方でhttpd.confの設定を行います。
LoadModule xsendfile_module modules/mod_xsendfile.so
#Xsendfileモジュールを使うかどうか。onにしなくちゃ始まらない。
XSendFile on
#もし、親ディレクトリやドキュメントルートの外側のディレクトリ内のファイルも出力できるようにするならonにする。
#セキュリティホールになる可能性もあるので慎重に。
XSendFileAllowAbove on
これで静的ファイルの出力をApacheに任せることができる様になってる筈です。
以下の様なPHPスクリプトを作ってブラウザからアクセスして正常にファイルがダウンロードできれば成功です。
試す前にApacheを再起動するのを忘れないでください。
if($logged_in){
$filename = 'hoge.gif';
header('Content-Length: ' . filesize($filename));
header('Content-Disposition: attachment; filename='.basename($filename));
header('X-Sendfile: '.$filename);
}ご覧のとおり、xsendfileモジュールを導入したApacheはPHPから出力されたHTTPヘッダにX-Sendfileというものがあればそのファイルを出力してくれます。もし、指定されたファイルが見つからなかったりパーミションがなかったりした場合は404エラーを吐きます。
次に、Apacheで静的なファイルをメモリ上にキャッシュするようにしましょう。
Apacheでのキャッシュについての詳細は
mod_cacheのドキュメントやmod_mem_cacheのドキュメントに書いてあるんですが、とりあえずはhttpd.confの末尾にでも
CacheEnable mem / #キャッシュのストレージタイプとキャッシュを許可するディレクトリ。これだとメモリ上にドキュメントルートの下の静的ファイルは何でもキャッシュする。
MCacheSize 40960 #キャッシュに用いるメモリ容量(キロバイト)※バイトではない。
MCacheMaxObjectCount 10
MCacheMinObjectSize 1
MCacheMaxObjectSize 20480 #1ファイルの最大サイズ(バイト)※キロバイトではない。
という設定を追加してやると良いでしょう。
大きなファイルをダウンロードするような場合はApacheの機能を使おうがPHPから出力してやろうがさほどパフォーマンスは変わらないと思いますが、数キロバイトの画像ファイルを大量に出力するような場合においてはかなりのパフォーマンスアップが期待できます。
今回はPHPを使った例で説明しましたが、RubyでもPerlでもとにかくX-SendfileというHTTPヘッダさえ吐き出せばどんが言語でも利用可能なテクニックですので興味がある人は(私の代わりに)試してみてください。
PHPで4GB以上のファイルのファイルサイズを取得する方法
PHPにはファイルサイズを取得するfilesize()という関数があるが、これは4GB以上のサイズのファイルでは正常に動いてくれない。
4GB以上のファイルのファイルサイズを得るには以下の様にすると良い。
$file = 'hogehoge.dat' //サイズを知りたいファイルのパス
$INT = 4294967295;
$size = filesize($file);
$fp = fopen($file, 'r');
fseek($fp, 0, SEEK_END);
if (ftell($fp)==0) $size += $INT;
fclose($file);
if ($size<0) $size += $INT;
echo $size; //ファイルサイズ(バイト)を表示
Railsアプリが「Rails application failed to start properly」とエラーを吐く原因
手元のCentOS5.2(32bit)にRuby on Rails入れて、Apache2.2 + passenger 環境でRedmineを使えるようにしたが、ブラウザからアプリのページにアクセスしても「Rails application failed to start properly」と怒られて、これの対処にけっこうハマってしまった。
慌ててググって最初に見たページが「さくらのレンタルサーバに Redmine をインストール」で、そこを参考に environment.rb をひたすらいじったがダメ。
しばらくウニウニ悩んだ結果、原因はRedmineのデプロイディレクトリに対してapacheが適切なパーミションを持ってなかっただけだった。
chown -R apache:apache redmine
で一発解決した。
Win32版MySQL5.1とPHP5.2.9-2って相性わるいのか?
WindowsXPにPHP5.2.9-2とMySQL5.1を入れたらPHPからMySQLに接続できなくなりました。
いろんな設定いじってもダメ。結局MySQLを5.0に戻したらすんなりつながった。
Firefoxプラグイン「Organize Status Bar」の問題
同じようなトラブルで困っている人が無駄な時間を使わなくていいようにメモ。
ステータスバーのアイコンの並びを自由に変更できる便利なアドオン「Organize Status Bar」。
Firefox3.0.10にも導入してみたが、コイツを入れるとツールバーのカスタマイズができなくなる。
もし、ツールバーに表示するアイコンの追加や削除をしたい場合は、一旦Organize Status Barを無効化してから作業する必要がある。
私は大量にアドオンをインストールした状態でこのトラブルに見舞われたものだから、最終的にOrganize Status Barが原因だと突き止めるまでにアドオンを一つずつ無効化して試行錯誤を繰り返した。
featureってどう発音しますか?
私はプログラミング言語についてもそうであるが、言葉に対してはそれ以上にかなり保守的である。
言葉というものはコミュニケーションの道具の一つであるが故にそれが使われる世代や使う人々を取り巻く環境に応じて自由に改変し、より正確かつ円滑なコミュニケーションが行われるように進化していくべきであるとは思う。しかし、昨今の巷で耳にする日本語はその軌道を外れ、どこか迷走しているように感じられてならない。
こう書くとどうせまた若者の言葉遣いを批判するだけだと思われるかもしれないが、私は若者の話す言葉が汚くて聞き苦しいと言っているのではない。子供たちにとっては言葉さえ遊び道具の一つだと考えれば、彼らが子供の間に言葉をどう崩して使おうが、いずれ大人になった時に正しい言葉を使えるようになるならば一向に構わないと思う。
だが、「若者の言葉は乱れている」と嘆く大人や言葉の見本を伝えるべきアナウンサーまでもが誤った言葉を喋り、尚且つ本人たちは自分たちの言葉の乱れには気づいていないことに対して、私は強い危機感を覚えているのだ。
例えば、「かなり」という副詞の発音は「か」にアクセントを置くのが正しく、アナウンサー達は長年そう発音してきた。しかし、最近では若者がよく使う「な」にアクセントを置いた発音をするアナウンサーが目に付くようになってきた。特にアイドルまがいの女子アナに多い気がする。ニュースを読み上げる時、彼女たちはさも自分は可愛い顔して教養もあるエリートであるとでも思っているかのようなすまし顔をしているが、彼女たちの言葉の中にお馬鹿な学生時代の名残を見つけてしまった時、私は日本語の見本としてのアナウンサーに失望し、日本語に対する危機感を強く感じてしまう。
また、最近特に気になるのが芸能人やラジオのDJなどが「feature」を「フューチャー」と発音していることだ。外国語をカタカナ発音すること自体に無理があることも多いので、ある程度変な発音になることは許容すべきだが、この場合はスペルを見ても実際のアメリカ人の発音を聞いても「フィーチャー」と発音されるべきことは明らかである。「フューチャー」では未来になってしまう。こんな基本的な事に何の違和感も感じずに平気で公共の電波で間違った発音を披露出来る程までに日本人の面の皮は厚くなってしまったのだろうか。
かと思うと一部では異常なほど言葉に神経質になっている場面も見られる。ある時期若者言葉を批判するために「ら抜き言葉」というワードが持てはやされて以降は過敏に「ら抜き言葉」を意識し、不自然なくらいに「ら」が大量に埋め込まれた言葉をテレビから聞くようになった。「このカメラは簡単に撮られます」という文は尊敬語なのか受け身なのか可能動詞なのか区別がつきにくい。「おでこで卵を割られます」も同様だ。もうずいぶん長い間「撮れます」や「割れます」という「ら」抜き表現が若い世代からお年寄りまで違和感なく使われてきたのだから、今さら文法原理主義的に「ら」を使うのは言葉の自然な進化の過程から外れている感がある。
これと同様に「させていただきます」も過度に文法を意識した故に不自然に使われだした言葉だろう。他人から何かを見せてもらう時に「見させていただきます」という表現をタレントやアナウンサーが当たり前に使っているが、これも我々の日常会話では「見せていただきます」が自然である。「ら」抜きの反動で過剰に「ら」を入れたというロジックが、「さ」にも適用された例だろう。おまけに「させていただきます」という言葉は普段はあまり多用されない上に発音しずらい言葉であるから喋りを商売にしている人間は格好つけるために敢えて多用したがるのかもしれない。
かつてはテレビやラジオで聞く言葉は美しい見本となるものであったはずだ。だが、今ではそうしたマスメディアさえ日本人の言葉の乱れの元凶のひとつとなっている。さらに、彼ら自身はその自らの過ちに気づいてか気づかでか、時に不自然なまでに文法を意識した言葉を流しては得意になっている。このように、正しい文法も、自然と崩れた常用語も無視した不自然な言葉を一方的に発信するマスメディアによって私たちの言葉が変化していくならば、これは本来の言葉の進化の軌道を大きく外れていると感じざるを得ない。



