Smartyの文字化け必須

最近、Smartyの導入の話があり初めて使用しているのですが、テンプレートに{$var}のように中カッコをつけて変換する方法です。これを使うとPHPなのにPerlでテンプレートを使った感じのページが作成できるので面白いです。

このタイトルでピンと来た方もいるかも知れませんが、テンプレートの中に「必須」と書き込んだときにエラーを発生してしまいます。これは文字コードがShift-JISの場合に 須 の字の2バイト目が } なので間違った解釈をされてしまうためです。それであれば最初からEUCで作るとか、変換するという手もありますが、クランアントがShift-JISで表示する仕様だったり、特殊文字を使用していてnkf等を利用すると文字欠けや化けを起こす場合はとても悩むと思います。

フロートタイプの掲示板や携帯電話向けコンテンツはこの部類になりますが、私が行った一番簡単な解決方法は必須という文字が必要な場合は変換必須にするだけ。

つまり、文字化けを起こすのはPHPではなくSmarty側なのでテンプレート側に必須を書かなければ良い。

index.tpl内に必須の文字があれば具体的にはこのようにする。

必須→{$hissu}

そしてindex.phpにはassainを追加する

$o_Smarty->(“hissu”,”必須”);

こんな感じです。

デバッグ完了

UNIX版から開発しているから、次にWindowsで動かす時のデバッグに時間が掛かった。原因はFD_SETSIZE絡み。UNIXだとFD_SETSIZEのサイズは1024で以下のようにディスクリプタが振られた。

0…標準入力
1…標準出力
2…標準エラー出力
3…ソケットサーバー
4…クライアント1(telnet)
5…クライアント2(telnet)

この時点では数の少ないほうからディスクリプタが振られ1024には遠く及ばないので特に問題ではない。

これがWindowsだとコマンドプロンプトから起動した場合

1956…ソケットサーバー
1928…クライアント1(telnet)
1912…クライアント2(telnet)

直接実行ファイルをダブルクリックして起動した場合でも、

96…ソケットサーバー
124…クライアント1(telnet)
140…クライアント2(telnet)

といった感じで肝心のFD_SETSIZEは64で定義されている為、そのままでは役に立たないどころかオーバーフローを起こしてサーバーが落ちてしまっていた。結局Windowsの場合はFD_SETSIZEを2048に再定義するという方法で逃げた。正直ココまでばらついているとループ回数が増える分不利な気がする。

この時点でチョットの変更でFLASHクライアント用になれるチャットサーバーができました。サーバー自身はデータの中身について全く検査はしてないのとバッファは固定値なので大量にデータを送ると最大値以降の文字は削除されてしまうくらいです。

ソースのダウンロードはこちら(EUC)
socket_server_select

diffとpatch

これは便利いいなー。今時はcvsというツールもあるが、そっちの方はまだよく使い方が判ってないので暫くはdiffで。

まず、hello.cの中のprintf文で表示するテキストの内容を変えてみる。差分を取るためには2つファイルが必要になるのでhello.cとコピーした後編集したファイルのhello2.cを作成。

# cp hello.c hello2.c
# vi hello2.c

次にdiffコマンドを使い差分をとる、因みにオプション無しの場合はファイル情報が出力されなかったのでpatchの当て方が判らなかったので-cか-uを使用する。両者の違いは次の通り。

# diff -u hello.c hello2.c
— hello.c Fri Dec 23 17:56:29 2005
+++ hello2.c Fri Dec 23 17:58:05 2005
@@ -2,7 +2,7 @@

int main()
{
– printf(“Hello, world!n”);
+ printf(“ハローワールド!n”);
return 0;
}

# diff -c hello.c hello2.c
*** hello.c Fri Dec 23 17:56:29 2005
— hello2.c Fri Dec 23 17:58:05 2005
***************
*** 2,8 ****

int main()
{
! printf(“Hello, world!n”);
return 0;
}

— 2,8 —-

int main()
{
! printf(“ハローワールド!n”);
return 0;
}

-cだと2つのソース全てを書き出してかなり冗長している。これなら-uでいいかな。通常はこれを差分ファイルとして保存するのでコマンドは『diff -c hello.c hello2.c > hello.diff』の様にする。

そして、実際にhello.cをhello2.cの状態にするには、
# patch < hello.c
でOK。もう一度同じコマンドを使用すると確認を要求されるがpacheを当てる前に戻してくれる。