imapモジュールのエラーの吐き方が面妖な件
PHPのエラーログに下記のような謎のエラーを発見。
[05-Feb-2008 21:10:40] PHP Notice: Unknown: Unterminated mailbox: ya ndo@localhost (errflg=3) in Unknown on line 0 [05-Feb-2008 21:10:40] PHP Notice: Unknown: Unexpected characters at end of address: <wbr>aaa@aaa <wbr>bbb.jp> (errflg=3) in Unknown on line 0
「in Unknown on line 0」とはアツいですね。
PHP5.2.5のソースの中を検索しても「Unexpected characters」なんてメッセージは無い。
ググってみるとどうやらIMAPが返すエラーメッセージらしく、IMAPモジュールの中を見てみると怪しいのがありました。
PHP_RSHUTDOWN_FUNCTION(imap) { ERRORLIST *ecur = NIL; STRINGLIST *acur = NIL; if (IMAPG(imap_errorstack) != NIL) { /* output any remaining errors at their original error level */ if (EG(error_reporting) & E_NOTICE) { ecur = IMAPG(imap_errorstack); while (ecur != NIL) { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s (errflg=%ld)", ecur->LTEXT, ecur->errflg); ecur = ecur->next; } } mail_free_errorlist(&IMAPG(imap_errorstack)); }
なんでも imap_errorstackが空じゃなかったら、入っている内容を全部E_NOTICEで吐いていくという事らしい。
おまけにこれを PHP_RSHUTDOWN_FUNCTION で宣言してるので、モジュールの終了処理で行うという事に。
あーそのせいで Unknown in 0 になってるような気がしますね。
ちなみにIMAPGはこういうマクロでした。
http://cvs.php.net/viewvc.cgi/php-src/ext/imap/php_imap.h?annotate=1.32.2.2.2.2&pathrev=PHP_5_2#l213
# define IMAPG(v) TSRMG(imap_globals_id, zend_imap_globals *, v)
パラメーターをキーにしてThreadSafeResourceManagerから構造体を取ってくる?ってことですよね。
このエラーをとめるにはimap_errorstackが空になるように使えばよいので、imapに渡しているパラメータを見直すか、
PHP_FUNCTION(imap_errors) { ERRORLIST *cur=NIL; if (ZEND_NUM_ARGS() > 0) { ZEND_WRONG_PARAM_COUNT(); } if (IMAPG(imap_errorstack) == NIL) { RETURN_FALSE; } array_init(return_value); cur = IMAPG(imap_errorstack); while (cur != NIL) { add_next_index_string(return_value, cur->LTEXT, 1); cur = cur->next; } mail_free_errorlist(&IMAPG(imap_errorstack)); IMAPG(imap_errorstack) = NIL; }
これを呼んでやればスタックが空になるようです。
マニュアルにも書いてありました。alertsの方も何か入ってるとまずそうですね。
http://jp.php.net/manual/ja/function.imap-errors.php
それにしてもなんでエラーを受け取った時に出力しないでスタックに貯めるんでしょうね。
おまけにそれを終了処理で出力するっていうのはPHPモジュールとして一般的な実装なんだろうか・・・。
読み方間違っている所があればご指摘ください。