[PHP-users 15441]Re: メール受信時の自動処理について

Osamu Shigematsu shige @ ravi.ne.jp
2003年 5月 22日 (木) 05:37:15 JST


重松です。こんにちは。

On Thursday, May 22, 2003, at 03:49 Asia/Tokyo, Tatsuya Kondo wrote:

> ありがとうございました。
> 話を戻しますが、改行コードが異なると言う事は、
>
> list($head, $body) = split("\r\n\r\n", $buffer, 2);
> if(!$body)
> {
>     list($head, $body) = split("\n\n", $buffer, 2);
> }
>
> とでもしないとやばそうですね。

split() の最初の引数は、「正規表現」です。
だから、CR+LF, CR, LF どれがきても、一行で分割できますよ。

具体的には、

	( CR LF もしくは CR もしくは LF ) が 2 回

を表現すればよく、

	"(\r\n|\n|\r){2}"

となります。

<?php
$x = array("1\n\n2","3\r\r4","5\r\n\r\n6");
foreach($x as $y)
	var_dump(split("(\r\n|\r|\n){2}", $y, 2));
?>

コマンドライン版 (PHP 4.3.1) でテスト:
$ php test.php
array(2) {
   [0]=>
   string(1) "1"
   [1]=>
   string(1) "2"
}
array(2) {
   [0]=>
   string(1) "3"
   [1]=>
   string(1) "4"
}
array(2) {
   [0]=>
   string(1) "5"
   [1]=>
   string(1) "6"
}

それから、PHP の場合、正規表現と一口にいっても、

	(1) ereg 系
	(2) pcre 系 (Perl 互換)
	(3) mb_ereg 系 (Ruby 互換)

の 3 種類あり、split は、特殊なことをしないと、
(1) の ereg 系になります。

で、

	(1) split
	(2) preg_split
	(3) mb_split

が上との対比になります。

そして、それぞれ、微妙に文法や「挙動」が異なりますから、
厳重な注意が必要です。

ereg 系は、マルチバイト文字を考慮しませんから、
場合によっては、不適切な位置で、文字が分割され、
結果として、データを破損する危険があります。

今回は、7bit データですし、8bit でも、UTF-8(N) の場合、
あるいは、0x20 より下の場合、マルチバイト文字の 2 バイト目以降に
くることはなかったと記憶していますから、問題はないと思います。
# PHP が UTF-8 は BOM を付加してはいけません。
# ただし、[] (クラス) を使用する場合には、注意が必要です。

さらに、現状「バイナリセーフでない」ことが知られていて、
今回のようにメールデータを扱うなら、
おそらく問題はないでしょうが、
NULL byte attack 脆弱性を孕んでいることに留意して下さい。

	http://www.ravi.ne.jp/%7Eshige/?NullByteAttack

ちなみに、(2), (3) はコンパイル時に指定して、
オプションを有効にしなければなりません。
そして、それらを確認するには、phpinfo() を使用します。

$ echo '<?php phpinfo() ?>' | php | w3m -T text/html

また、(3) は、PHP 4.0, 4.1 系統, 4.2 系統は別途、
拡張のコードを自ら用意しなければなりません。
この時、PHP 自身の拡張方式が 4.2 で変更されたことを受けて、
4.0. 4.1 系統と 4.2 系統のソース互換性が損なわれています。

4.3 からはふじもとさんの国際版がマージされて、
マルチバイト拡張機能は標準でソースがそろっています。
が、残念ながらデフォルトでは無効なので、
configure script 実行時にスイッチで指定する必要があります。

	http://www.ravi.ne.jp/%7Eshige/?PHP4.3.0

結論として、マルチバイト文字を扱う場合、PHP 4.3.1 を利用して、
コンパイル時に、pcre, mbregex を有効にして、
利用することをおすすめします。

-- 
Osamu Shigematsu http://www.ravi.ne.jp/%7eshige/



PHP-users メーリングリストの案内