Category: Tips

今までの流れからするとだいぶ唐突なネタだが、仕事で半日苦労したのでメモしておく。

まとめていたらえらく長文になったので先に結論。

  • Postfixのaliasは正規表現を使ってマッピングできる
  • Postfixでlocalがregexpを使う場合ローカルパートしか渡さない(らしい)
  • $_ENVがnullの場合はphp.iniのvariables-orderディレクティブをチェック

●メールでデータを受け取りたい

ご存知の通り、携帯はブラウザのフォームからMultipartでPOSTできないようになっている。つまり、ファイルのアップロードができないということだ。ユーザからテキスト以外のデータ投稿を受け付けようとすると、メールに添付してもらうしか方法がない。

一方、携帯のユーザの行動パターンには「メールアドレスをころころ変える」という特徴がある。個人的には気に入ったアカウントは長く使いたいと思うのだが、若年層のケータイユーザはそうではないらしい。となると、ユーザ側で簡単に変更できるメールアドレスをキーにするのはあまり都合がよろしくない。それ以外の情報でユーザを識別する必要がある。

●メールを送ってきたユーザを識別したい

私が担当しているコンテンツの前任者は、以下の手段でメール送信ユーザを識別していた。

  • ユーザIDを適当に暗号化
  • mailto:タグのbody要素に仕込む
    →クリックすると本文が入力された状態で端末のメーラが起動する
  • 受信したメールをパーズしてユーザIDを復号

正直あまりよろしくない方法である。ユーザが本文にテキスト情報を付与して送信することができないし、本文のキーをいじられるとあまりいいことはない。

一方、例えばmixiの「携帯で日記を投稿する機能」などは、ローカルパート(メールアドレスの内「@」以前の部分」に識別キーを入れて送るようになっている。これによってメールのsubjectが日記のタイトル / メールのbodyが日記の本文 / 画像が添付されていれば写真投稿、というメール一通で日記投稿を完結させることが可能になる。

ああ前置きが長くなった。つまり、ローカルパートに情報を載せたメールを処理するための設定方法をメモしておく、というのが本題である。

(さらに…)

前回(たくさんのパラメータを効率よく管理する)で触れたYAMLハンドラ。SyckよりはLibYAMLのほうがよさそうだな…とも思ったのだが、Windowsローカルに開発環境を作るのが非常に大変なので、相変わらずSpycを使うことにした。キャッシュはPEAR::Cache_Liteに変更して、読み込みだけキャッシングするラッパを実装してみた。

(さらに…)

こちら(狐の王国 PHPの本当の利点)にあるように、PHPは標準のドキュメントが非常に充実していて、しかもほぼ全文日本語訳されている。レベルの低い参考書を買うぐらいなら、PHPマニュアルのそれっぽいところを見たほうがよっぽどいい。

もちろんオンラインヘルプ(PHP / PEAR)を使ってもいいのだが、ダウンロードできる完全版があるならそれを手元に置いておく方が気分的にもネットワークリソース的にもよいだろう。

ダウンロードできるヘルプ(PHP / PEAR)も至れり尽くせりで、巨大なHTMLファイル / 分割されたHTMLファイル / Windows HTML Helpの3種類(と、PEARはさらにプレーンテキスト)が用意されている。

ダウンロードページは英語だが、どちらも「Japanese」の行を探し、目的のファイルをダウンロードすればいい。ただし、Windows HTML Help(chm)を使う場合は注意が必要である。ダウンロードページにはでかでかと書いてあるのだが、英語だったのであっさりスルーしていた。ちょっと反省。

If you are using Microsoft Internet Explorer under Windows XP SP2 or later and you are going to download the documentation in CHM format, you should "unblock" the file after downloading it, by right-clicking on it and selecting the properties menu item. Then click on the ‘Unblock’ button. Failing to do this may lead to errors in the visualization of the file, due to a Microsoft bug.

XP + SP2の環境だと、ファイルのプロパティで「ブロックの解除」をクリックする必要がある。ググればすぐに解決する問題なのだが、文章としてまとめておくことことも大事だとググったときに実感したのでエントリしておく。

PHP: PHP マニュアル – Manual
http://www.php.net/manual/ja/

PEAR :: Manual :: PEAR マニュアル
http://pear.php.net/manual/ja/

PHP: Download documentation
http://www.php.net/download-docs.php

PEAR :: Documentation
http://pear.php.net/manual/

【WinXP】chmファイルが正常に表示されない – FREEBOX IV
http://blog.goo.ne.jp/freebox_tk/e/cb3f50dcd603e04ef3b7bf3268cf6127

XPで、chmファイルが表示できない? – Fuzyのプログラミング(?)メモ – 楽天ブログ(Blog)
http://plaza.rakuten.co.jp/pgmemo/diary/200510290000/

ちなみにchmだとなぜか「Exceptions」のページが表示できないのが微妙に不便。仕方なくオンラインヘルプだけ単品でブックマークしている。

どうもとある処理に時間がかかってるような気がする。そんなときはきちんと時間を計測しよう。もちろんこの方のようにストップウォッチ片手に計測してもいいが、いやしくもプログラマのはしくれならプログラムで解決しよう。

…とか書くのも恥ずかしくなるぐらい簡単なコードで恐縮である。このコードに関してはコピペして使っていただいてもまったく構わない。コピペするより書いたほうが早いくらいだし。

見かけどおりPHP4でも動くはず。PHP5だとmicrotime()が引数を取る(trueを指定するとfloat値が返ってくるので単純に引き算すればいい)のでもっと簡単なコードになる。

getNowメソッドがちょっと冗長なのは、Lap機能も作ろうとしてやめた形跡だった記憶がある。

【StopWatch.php】

<?php
class StopWatch
{
    var $start_sec ;
    var $start_msec ;
    var $stop_sec ;
    var $stop_msec ;
    function start()
    {
        $this->getNow("start") ;
    }
    function stop()
    {
        $this->getNow("stop") ;
    }
    function getNow($kind)
    {
        $sec"{$kind}_sec" ;
        $msec = "{$kind}_msec" ;
        list($this->$msec, $this->$sec) = explode(" ", microtime()) ;
    }
    function dispTime()
    {
        echo "start:" . ($this->start_sec + $this->start_msec) . "\n" ;
        echo "stop :" . ($this->stop_sec  + $this->stop_msec)  . "\n" ;
        $sec  = $this->stop_sec - $this->start_sec ;
        if ($this->start_msec > $this->stop_msec)
        {
            $msec = ($this->stop_msec + 1.0) - $this->start_msec ;
            $sec -= 1 ;
        }
        else
        {
            $msec = $this->stop_msec - $this->start_msec ;
        }
        echo "time :" . ($sec + $msec) . "\n" ;
    }
}
?>

【example】

<?php
require_once 'StopWatch.php' ;
$sw = new StopWatch() ;
$sw->start() ;
// 計測対象の処理
while (true)
{
    // do something.
}
$sw->stop() ;
$sq->dispTime() ;
?>

データベース接続パラメータ、テンプレート関数の色定義、絵文字などの各種変換テーブル、その他もろもろ…。webアプリケーションにはたくさんの設定項目(パラメータ)が存在することだろう。それらをどうやって定義・管理するかはなかなか悩ましい問題である。defineを山ほど書いてrequire_once?constだらけの定数クラス?配列が便利だからserializeしてファイルに書いておく?どれも一長一短だなぁ。

前代フレームワークの実装時、やはりこの問題に突き当たっていろいろと検討していたら、YAMLというデータフォーマットに行き当たった。テキストなので可読性が高く、パーサを使えば読み込んだ文字列を連想配列に落としてくれる。Rubyは1.8から標準でライブラリが添付らしい。むーうらやましい。

PHPではSyck(Rubyにも組み込まれているライブラリ)もしくはSpyc(ピュアPHPのライブラリ)から利用することになる。前代フレームワークでは導入の手軽さからSpycと、パフォーマンスのためにCacheYAMLというクラスを参考に書いたキャッシャクラスで運用している。

導入してみた感想は…「なぜもっと早くやらなかったのか?」。管理が簡単で、環境ごとの設定差分も同一ファイルで管理できる(メモリ効率は悪くなるが)。10万hit / day程度のモジュールに導入しても特に問題は発生していないので、パフォーマンスも問題なさそうだ。

kwappaではパフォーマンス向上のためにSyck + PEAR::Cache_Liteによる組み合わせも試してみる予定である。ConfigManagerクラスとしてまとまる予定なので、いずれエントリしようと思っている。

Spyc + CacheYAMLでの導入は簡単なのでコードは略。以下のリンクを参考にされたい。開発者・記事を書かれた方々には大変感謝している。

 

The Official YAML Web Site
http://yaml.org/

YAML – Wikipedia
http://ja.wikipedia.org/wiki/YAML

XMLの論考: YAMLはXMLに改良を加える
http://www.ibm.com/developerworks/jp/xml/library/x-matters23/

spyc: a simple php yaml class
http://spyc.sourceforge.net/

Do You PHP? – PHPでYAMLを扱う
http://www.doyouphp.jp/tips/tips_yaml.shtml

cl.pocari.org – PHP 用 YAML パーサ spyc の結果をキャッシュする方法
http://cl.pocari.org/2006-03-17-2.html

言語別 YAML用ライブラリ徹底解説:第4回 PHP編|gihyo.jp … 技術評論社
http://gihyo.jp/dev/serial/01/yaml_library/0004