ようこそゲストさん

CPA-LABテクニカル

メッセージ欄

2008年6月の日記

2008/06/30(月) PHPの日本語デフォルトコードはEUC-JP

php.ini が
mbstring.language = Japanese
であり、かつ、mbstring.internal_encodingが未設定の場合、PHPは、mbstring.internal_encodingが、文字コードEUC-JPであるとみなして動作する。*1
ちなみに、languageの設定さえない場合は、ISO-8859-1のようだ。

時代は、UTF-8だと思いますので、UTF-8でソースコードを書く時には、
mbstring.internal_encoding = UTF-8
を忘れずに。

可搬性を重視した場合

他の環境でも動作させることを考えれば、これらの項目は、php.iniで設定するのでなく、自分のスクリプトの初期設定で行うほうがよい。だって、レンタルサーバーであれば、languageの設定がjapaneseと保証されているわけでもないし、文字コードもphp.iniでどう設定されているかは、千差万別(のはず)だからだ。
よって、日本語のコードであれば、必ず初期設定スクリプトで、
mb_language( 'ja' );
mb_internal_encoding( 'UTF-8' );
を設定しましょう。

なぜ今?

何を当たり前のことをお思いでしょうけど、mbstring.internal_encodingを未設定、またはEUC-JPのままで、UTF-8でコードを書くと思わぬ誤動作が生まれる可能性がある、ということで。。。。次回に続く。

*1 : PHP5.2.4 PHP_RINIT_FUNCTION mbstring-mbstring.c

  • mb_encode_mimeheaderの都市伝説を検証する CPA-LABテクニカル spok
    ■mb_encode_mimeheader都市伝説mb_encode_mimeheaderは、なんか使いにくい。文字化けする。とあまり良い評判を聞きません。私も、「使うのはちょっと怖いな」と思っていました。しかし、mb_encode_mimeheaderは...

2008/06/22(日) mail関数(PHP)のハマりどころ

はてなブックマークの情報 はてなブックマークに登録 はてなブックマーク数 qdmailspok
Qdmailは原則としてPHP標準のmail関数を使用している*1
このPHPのmail関数は何かとクセがあり*2、特に改行コードでは苦労させられた。
マニュアル(mail)を熟読すれば、載っていることばかりだけど、今後のために整理しておく。

改行コード

インターネットメールの世界では、改行コードは原則として、CRLFである。それは、RFC2822を参照されたい。SMTPサーバーに直接渡す時は、これでOK。
しかし、PHPのmail関数には時と場合により、LFで渡さなければならない時がある。
特に、ヘッダーと本文の改行コードは分けて考える必要があるので、注意すること。
mail関数の改行コード注意点
  • 本文の改行コードはLFで渡すこと*3
  • ヘッダーの改行コードは、原則としてCRLFだが、MTA(送信サーバー)によっては、LFで渡さなければならない場合がある。現在、LFで渡さなくてはならないMTAは、qmailであることが判明しているが、他もあるかも知れない。qdmailとqmailをごちゃごちゃにしないよう留意を。

混乱しがちな点

本文はLF。
subject以外のヘッダーはCRLFで渡さなくてはならないのが、面倒なところ。

たぶんlinux,unix系のサーバーは、OS標準の改行コードがLFであることから、このようにしているように思うけど、それならヘッダーもLFで渡すようにすればいいのに。。。。

こちら(PHPのmail()のできの悪さ-よくきたblog)でもご指摘ありますが、ちょっと、その実装は。。。。

Windows版の制限

to引数
Windows版のmail関数は、第1引数のtoでは、
name<address@example.com>
が使えず、
address@example.com
しか許されない。
私の環境では、sendmaneというsendmailのラッパーを使わせていただいてるので、この制限はないけれど。
ピリオドだけの行
PHP が SMTP サーバと直接通信をする際、ピリオドから 始まる行は無視されます
FromとReturn-Path
Windows では、From ヘッダを設定すると Return-Path も設定されます。

送信サーバーがqmailかどうかの判別

Qdmail0.8.6aでは、ini_get('sendmail_path');でもってPHP.iniのsendmail_pathを読み取り、そこに、qmailという文字列があるかどうかで判別している。
これだと誤判別もあり得るので、他にもっといい判別方法があったら、ぜひ教えて下さい。

参考にさせていただいたサイト

qmail の RFC 違反
PHPのmail()のできの悪さ-よくきたblog

*1 : SMTP送信もできるけど

*2 : PHPのせいじゃない部分も多々あるけど

*3 : PHPがCRLFに変換するようです。

  • SMTP送信を使うべき3つの理由-PHP CPA-LABテクニカル spok
    ■さらば、mail,mb_send_mail関数SMTP送信を使うべし!mail,mb_send_mailはトラブルの元改行コードこちらmail関数のハマりどころ でも書いたように、mail関数は、改行コードが難解である。mb_send_mailも、文字化...

2008/06/21(土) QdSimpleMailで簡単テキストメール-PHP

はてなブックマークの情報 はてなブックマークに登録 はてなブックマーク数 qdmailspok
簡単にテキストメールを送りたいだけなのに。。。という要望をかなえるためのPHPメール関数。
簡単軽量PHP日本語テキストメール関数-QdSimpleMail
制約の多いmb_send_mailの代替関数を目指しました。
Qdmailは、いろいろ機能を欲張りすぎたので、3000行を超えるソースコードになってしまいましたが、QdSimpleMailは、たったの200行強。

なんとなく動作が不安定なPHPのmb_encode_mimeheaderを使わずに、自作のMIMEエンコーディング関数で動作しています。

特徴

続きを読む

2008/06/16(月) PHPマルチバイト文字連結の罠(JIS,ISO-2022-JP)

Qdmail開発覚書。インターネットメールで日本語を使用する場合、iso-2022-jp(JIS)と呼ばれる文字セットを使用することが一般的である。しかし、日本語メールの処理をしようとして、iso-2022-jpで文字列処理を行うと、エスケープシーケンスのせいで、ものすごい非効率、場合によってはエラーが発生する可能性がある。ちなみにutf-8,euc-jp,shif-jisは原則としてエスケープシーケンスを使用しないので大丈夫である。

どんな不具合?どんな非効率?

'あい' == 'あ' . 'い' が false になる時

続きを読む