PHP8.0にアップグレードしたらメールヘッダがおかしくなった話


タイトルの通り,PHP7.4からPHP8.0にアップグレードするとmail()で送られるメールの本文にメールヘッダの一部が表示されてしまいます。

mail
From - Sun Mar xx xx:xx:xx 2022
Delivered-To: hoge@foo.jp
Received: ............................
Date: .........................
To: hoge@foo.jp
Subject: the subject

From: bar@foo.jp

Mime-Version: 1.0

hello

1個目の空行から下がメール本文と認識されるためメール本文はこうなります。

メール本文
From: bar@foo.jp

Mime-Version: 1.0

hello

原因がわからず,とりあえずPHPMailerを入れてSMTP経由で対応しました。

PHPMailerの使い方はこちらを参考に。

(追記:2022/3/24 原因が判明しました)

php-src/ext/standard/mail.c(513~518行目)
		fprintf(sendmail, "To: %s\r\n", to);
		fprintf(sendmail, "Subject: %s\r\n", subject);
		if (hdr != NULL) {
			fprintf(sendmail, "%s\r\n", hdr);
		}
		fprintf(sendmail, "\r\n%s\r\n", message);

PHP7.4まではLFで出力していたのが,CR+LFに変更になった様子。

php.ini
sendmail_path = /bin/cat > mail

で吐き出してエディタで見ると,確かに全てCR+LFになってる。

/usr/sbin/sendmail -t < mail

とするとやっぱり受信メールのヘッダに空行が入ってしまう。

sakuraエディタで受信メール(.emlファイル)をよく見てみると

CR+CR+LFになってるな…。
ということで,どうやらPHP8.0で吐いたCR+LFをsendmailがCR+CR+LFに変換している模様。

とはいえ,PHP8.0でCR+LFで出力するのはどうしようもないので,sendmailに投げる前にnkfを挟んでPHP8.0が付けた改行コードCR+LFを一旦LFに戻してから,sendmailに送ってそこでもう一度CR+LFに変換するという力技...

php.ini
sendmail_path = "nkf -Lu | /usr/sbin/sendmail -t -i"

として解決しました。

これはsendmailが悪いのか?