miau's blog?

PHP いろいろ

PHP 周りでいろいろあったので、そのお話。
気がついたらまた長文に。


■DB_DataObject のエラー処理

DB_DataObject 使ってて、なんだかうまくエラーハンドリングできてない気がしてたんですが。

DB_DataObjectのエラー処理

とのことで、factory() メソッド以外はちょっと面倒らしい。

DB_DataObject のサンプルは腐るほどあるのに、エラー処理に言及されてる文書って少ないなぁ。
こんな状態で信頼性高いプログラム書けるのかな。

とりあえず、胡散臭いけど自分用のエラーハンドリング雛形。


$users = DB_DataObject::factory('USERS');
if (DB_DataObject::isError($users)) {
trigger_error($users->getMessage(), $E_USER_WARNING);
exit(1);
}

$users->user_id = $user_id;
$users->user_name = $user_name;

if ($users->insert() === false) {
trigger_error($users->_lastError->getUserInfo(), $E_USER_WARNING);
exit(1);
}

PEAR の使い方とか知らないし、未検証もいいとこなのであまり参考にしないほうがいいかも。


■trigger_error()

PHPポケットリファレンスによると、「第二引数に E_USER_ERROR を指定した場合、スクリプトの処理は停止される」ということだったんですが。
set_error_handler() でハンドラが登録されている場合はそうなるとは限らないみたいですね。

ということで、スクリプト終了したい場合は trigger_error('hoge', E_USER_ERROR); の後に、明示的に exit() したほうがよさげ。
このへん、汎用性に関する本とか読んだら普通に載ってるんだろうけど・・・何か良い本あったら教えてください。


■session_use_trans_sid

いつかちょっと書いた話題ですが。

PHP_SESSION_ID は通常 Cookie で渡されますが、QUERY_STRING として渡す方法もあります。
携帯電話向けのサイトだと後者の方じゃないといけないわけですが。

これを自動的判定&設定してくれる、session_use_trans_sid というパラメータがあるらしい。
php.ini を弄るのは面倒なので、ini_set() で設定できないかと思ったんですが・・・ダメみたいですね。

htaccess - SetEnvIf/Browsermatch & php_value

まぁ、大人しく php.ini いじる方向で。
ちなみに、Cookie 飛ばしてくるクライアントの場合、QUERY_STRING には自動設定してくれない様子。


■mb_send_mail() で文字化け

mb_send_mail() で長い日本語を改行なしで送った場合、途中から文字化けするらしい。


あああ(中略)あああ
$"$"$"(以下略)

986 byte 目で改行入る様子。

というか、日本語じゃなくても改行入るっぽい。


aaa(中略)aaa!
aaa(以下略)


990 byte 目で "!\r\n " が挿入されている模様。

「あああ(中略)あああ」のほうも、パケット拾ってデコード前のデータ拾ったらそういう状態だった。
(Becky! って生データ残らないから、結構不便・・・)
JIS の途中で強引に改行入れてるせいでそうなるんだろうな。

どのへんの問題なんだろう?ということで、調べてみると。

[PHP-dev 904]Re: mbstringのBUGではないでしょうか?
[PHP-dev 907]Re: mbstringのBUGではないでしょうか?

とのこと。
結局のところ、mb_string() の前に自前で改行入れとけ、と。

たまに ML とかで勝手に改行が入るものがあるけど、こういうことだったのね。
納得。


■Smarty の使い方

なんかせっかくのテンプレートエンジンを活かしきれてない場面が多いなー、とか。

たとえば、改行を含むデータを画面に表示したい場合。
他のと同じように、

<div class="message">{$message|escape:html}</div>

としても、改行が無視されてしまうので、確かにこれは問題。

だからと言って、PHP 側で

$message = htmlspecialchars($message); // HTML Encode
$message = nl2br($message); // "\n" => "<br />"

とかやって、テンプレート側で

<div class="message">{$message}</div>

とやるんではなく。

そういうのは、テンプレート側で

<div class="message">{$message|escape:html|replace:"\n":"<br />"}</div>

として処理すべきでは。

個人的に、こういう MVC っぽい部分は、
・Model は普通は DB だけど、ファイルなんかになっても問題ないように
・View(テンプレート)は普通は HTML だけど、plain text になっても問題ないように
Controller 側を作るよう意識しています。

そうすれば上記のような処理にはならないはず。


■addslashes()

上記とも絡むけど、SQL のサニタイジングで addslashes() を使うのは問題あるかと。
シングルクォートのサニタイジングで「\」を付加する DBMS ってむしろ特殊だし。

DB_DataObject 使ってるんであれば、

$users = DB_DataObject::factory('USERS');
$users->whereAdd("user_id = '" . $users->escape($user_id) . "'");


とか?
DB_DataObject::escape ってちゃんと DBMS の差異吸収してくれるのか、書いてて疑問になってきた。


■クッキーの破棄

JE no hitori chat: PHP session 使用時のログアウト処理

こんなの見かけた。

これってたぶん「行儀の良い Cookie の使い方」ってことですよね?

・session_destroy() すれば、サーバ側で SESSION ファイルが消去されるため、セキュリティ諸々の問題はない
・ブラウザに情報を残さないためには、上記のような処理が必要

という解釈なんですが・・・間違ってたらご指摘ください。>偉い人
posted at 22:55:26 on 2005-08-21 by miau - Category: Work No Trackbacks - Permalink

TrackBack

このエントリにトラックバックはありません
現在トラックバックは受け付けていません。

Comments

miau wrote:

「Smarty の使い方」のとこ。
わざわざ「replace:"\n":"<br />"」と書かなくても「nl2br」でいけることを最近知りました。
2006-04-06 17:10:08

Add Comments

現在コメントは受け付けていません。
お手数ですが、 こちら のコメント欄にでも記載していただければと思います。