Home > ソフトウェア > イサム開発で使ったプログラミング等のTips

イサム開発で使ったプログラミング等のTips

イサムの開発にあたって,いくつかの新しいテクニックを用いたので,新旧あわせて使ったテクニックを紹介したいと思います.

mod_rewriteでGETパラメータを変換

例えば,以下のようなURLを考えます.

http://4403.biz/ISAM/organization/NEC/

なんとなくパーマリンクっぽくて素敵ですよね.でも,この実体は以下のように処理したいと考えます.

http://4403.biz/ISAM/hoge.php?mode=organization&query=NEC

この変換をmod_rewriteで実現します.まぁ,Wordpressとかで使われている常套句ですね.mod_rewriteが有効な状態で,.htaccessに以下のように書きます.

RewriteEngine on
RewriteBase /ISAM/
RewriteRule "^(.*)/(.*)/$" "hoge.php?mode=$1&query=$2" [L]

簡単ね!ご存じだとは思いますが,これにGETパラメータがさらにくっつくような状況下では,QSAフラグも付けましょう.

hoge.phpでは受け取ったGETパラメータによって処理を振り分けたらいいと思います.これで実体を隠蔽しつつ,パーマリンクっぽいURLも提供できて,なんだかすごくいい感じです.クールURI!

mod_rewriteのBフラグ

上記の設定の後に,以下のようなアクセスを想定しましょう.

http://4403.biz/ISAM/organization/KDDI R&D Labs./

なんとなく上手くいかなさそうな気配がぷんぷんしますよね?実際にやってみると,このように展開されます.

http://4403.biz/ISAM/hoge.php?mode=organization&query=KDDI R&D_Labs_=

なんだか変なことになっている.紐解きましょう.GETパラメータがどうなっているかというと以下の通りです.

mode=organization
query=KDDI R
D_Labs_=

おい!って話ですね.問題点はR&Dの&をGETパラメータの接続詞と解釈してしまっています.解釈してしまっていますというか,それで正しいわけですが・・・.単純な解決策はURLエンコードです.しかし,そのためには,以下のようなアクセスを想定することになります.

http://4403.biz/ISAM/organization/KDDI%20R%26D%20Labs%2e/

こんなの恥ずかしくて見せられない!ということで,これをmod_rewrite中に実現したいわけですね.で,調べてみるとあるんですよ,これが.apache2.2.6以降らしいですが,Bフラグというものがあります.以下,引用.

B‘ (escape backreferences)
Apache has to unescape URLs before mapping them, so backreferences will be unescaped at the time they are applied. Using the B flag, non-alphanumeric characters in backreferences will be escaped. For example, consider the rule:
RewriteRule ^(.*)$ index.php?show=$1
This will map /C++ to index.php?show=/C++. But it will also map /C%2b%2b to index.php?show=/C++, because the %2b has been unescaped. With the B flag, it will instead map to index.php?show=/C%2b%2b.
This escaping is particularly necessary in a proxy situation, when the backend may break if presented with an unescaped URL.

mod_rewrite – Apache HTTP Server

簡単ね!というわけで,先ほどのRewriteRuleにBフラグを追加すると,こんなアクセスが来ても,

http://4403.biz/ISAM/organization/KDDI R&D Labs./

こんな風に渡されるので,

http://4403.biz/ISAM/hoge.php?mode=organization&query=KDDI%20R%26D%20Labs%2e

hoge.php側では$_GET[‘query’]をurldecodeしておけばいいですね.いい時代だね~.

memcachedの導入

インクリメンタルサーチでゴリゴリ検索させています.基本的にかなりの力業実装です.ですので,負荷を減らすためにキャッシュは重要になります.当初はMySQLのキャッシュ機能とAPCに丸投げしていたのですが,DBの更新が無ければ結果は不変なので,まるっとキャッシュしてしまえばいいのではないかと思ったので,memcachedしました.初挑戦です.

そもそもmemcachedとは何かといえば,以下のようなものだそうです.

Free & open source, high-performance, distributed memory object caching system, generic in nature, but intended for use in speeding up dynamic web applications by alleviating database load.

memcached – a distributed memory object caching system

ということで目的にピッタリです.で.基本的な使い方を確認しましょう.PHPではpecl::memcacheを使うのがいいのかな?似たものにpecl::memcachedもあります.よくわかりません.今回はmemcacheを使います.基本的な使い方は以下の通りです.

$mem = new Memcache;
$mem->addServer('localhost', 11211);
$val = $mem->get($key);
if(!$val) {
  //$valを作る作業
  $mem->add($key, $val, MEMCACHE_COMPRESSED, 3600);
}
$mem->close();

簡単ですね.これを応用して,イサムをキャッシュしまくります.方針としては,$keyをSQLクエリにして,$valをHTML出力文字列としています.つまりは,SQLクエリをキーにしてページフルキャッシュとほぼ同等です.これでキャッシュにヒットすればサックサクのはずです.

これをよくよく考えると,実行時間命なシステムでDBへの書き込みや更新がボトルネックになっている場合,とりまmemcachedにはき出しておいて,別プロセスで非同期にmemcachedから取り出してDBに格納するとかしてレイテンシを隠蔽できそう.そんなクリティカルなシステムを作ったことないですけどね.

エスケープとか

エスケープも別に珍しいことはしてなくて,strip_tagsやらmysql_escape_stringやらhtmlentitiesやらを使ってます.「エスケープは出力時に」という基本に忠実です.SQL文の構築はプレースホルダーを用いているので,そんなに変なことは起きないはずだと信じてます.攻撃しないで!

PHPの小ネタ

PHPはHTMLの中に直接スクリプトが書けるという実に変態な言語なので,様々な変態テクニックが駆使可能です.例えば,if文の途中でphp終了タグでぶった切って,HTMLを出力(というかそのまま表示)して,php開始タグで再びif文に復帰するとかいう常識的に考えられないような変態スーパーテクニックが利用可能です.可読性?なにそれ?誰が読むの?

それはそれとして,多少便利なものとしては,includeを用いたページ分割です.include命令によって別のphpファイルを読み込む(C言語の#includeのように)ことができるので,共通であるヘッダ部とフッタ部を別ファイルに分割することで,コード修正時の修正範囲を限定的にすることができます.ちなみに,これはHTMLヘッダ部でもできますので,かなり応用が利きますよ.

スーパーテクではありませんが,jQueryと組み合わせてajaxでインクリメンタルサーチやサジェストを実現しています.

Home > ソフトウェア > イサム開発で使ったプログラミング等のTips

Return to page top