目次
はじめに
- PHPのSwiftMailerライブラリを使って送信したメールの件名の一部が文字化けする現象を、素人なりに調査してみた話です
- 他の人が書いたソースを利用しているため処理内容はざっくりとしか把握できていません
- エンコードはShiftJis
- メーラーはThunderbird
したいこと
ほげほげシステムふがふが機能ぴよぴよ確認結果(NG)
という件名にしたいが、受信したメールでは
ほげほげシステムふがふが機能ぴよぴよ灰hネク惠比x?
になっている
「ぴよぴよ」の後ろから文字化けしているためこれを直したい
※ここでの件名は例なので適当です
やったこと
とりあえずソースを確認
Swift::init(function () {
Swift_DependencyContainer::getInstance()
->register('mime.qpheaderencoder')
->asAliasOf('mime.base64headerencoder');
Swift_Preferences::getInstance()->setCharset('shift_jis');
});
メール送信について調べていると文字コードはiso-2022-jp
で送信するのが主流のようでしたが、ここではshift_jis
で貫きます。
※この時点ではSwiftMailer
というものを知らないのでSwift~と書かれているものが何なのかはわかっておらず、雰囲気で読んでいました。
文字化けした部分の文字コードを調べる
予想
ShiftJisでは「確」は「8A6D」だが何故か別のエンコードになってしまっている。
例えばutf8の「8A6D」は「灰」なのかもしれない。
やってみる
文字化けしてない方(確認結果)と、文字化けした方(灰hネク惠比x?)の文字コードを書き出してみた。
JIS | SJIS | EUC | UTF-8 | UTF-16 | 字 |
---|---|---|---|---|---|
334E | 8A6D | B3CE | E7A2BA | 78BA | 確 |
4727 | 9446 | C7A7 | E8AA8D | 8A8D | 認 |
376B | 8C8B | B7EB | E7B590 | 7D50 | 結 |
324C | 89CA | B2CC | E69E9C | 679C | 果 |
JIS | SJIS | EUC | UTF-8 | UTF-16 | 字 |
---|---|---|---|---|---|
3325 | 8A44 | B3A5 | E781B0 | 7070 | 灰 |
68 | 68 | 68 | 68 | 0068 | h |
48 | C8 | 8EC8 | EFBE88 | FF88 | ネ |
38 | B8 | 8EB8 | EFBDB8 | FF78 | ク |
582A | 9CA8 | D8AA | E683A0 | 60E0 | 惠 |
16 | 16 | 16 | 16 | 16 | |
4866 | 94E4 | C8E6 | E6AF94 | 6BD4 | 比 |
78 | 78 | 78 | 78 | x | |
16 | 16 | 16 | 16 | 16 | |
? |
文字コード間違っていたらすみません
結果
関係性が見えてこなかったので文字コードが変わってしまってるとかではなさそう。
まぁ件名の途中から文字コードが変わって文字化けするなんて現象が実際にあり得るのかはわかりませんが...
メールのソースを読む
なんで最初に気づかなかったのか謎ですが、ソース見れば何か書いてあるんじゃねと思ったので見てみる
やってみる
「From:」や「To:」の後ろを見てみると普通にメールアドレスや差出人などが書かれている一方で、「Subject:」の後ろにはハッシュ値のような言葉が並び、=?shift_jis?
という言葉が含まれていました。Subjectは件名のことです。
何がなんだかさっぱりでしたがなんとなく関係ありそうな=?shift_jis?
で検索してみたら日本語の件名をShiftJisでエンコードしたってことみたい?
ネットに転がってたデコードツールで「Subject:」の後ろをコピペしたものをデコードしてみたら文字化けした件名(~ぴよぴよ灰hネク惠比x?)が出てきたので多分そういうことかな。
結果
関係がありそうなところは見つからなかった
初心に戻ってみる
Swift::init(function () {
Swift_DependencyContainer::getInstance()
->register('mime.qpheaderencoder')
->asAliasOf('mime.base64headerencoder');
Swift_Preferences::getInstance()->setCharset('shift_jis');
});
文字コードのことは一旦忘れてソースを理解してみようと思い、Swiftなんたらを調べることに。
やってみる
普通にSwift
って打つとiOSアプリを作るのに役立ちそうな情報が出てきそうだったので「Swift php メール」とかで検索してみると、Swift Mailerというライブラリがあるらしい
なるほどそれならと「Swift Mailer Subject 文字化け」で調べてみたところそれっぽい記事を発見(symfony1.4の「SwiftMailer」を日本語対応(iso-2022-jp)してみた)
どうも、Subjectが長いと文字化けするみたい。
ググって見ると、どうも前のバージョンのSwift Mailerも長い日本語は文字化けするという情報が。
とのこと。まじか。
ということで件名をいじいじして実験してみる
これが | こうなる | 結果 |
---|---|---|
ほげほげシステムふがふが機能ぴよぴよ確認結果(NG) | ほげほげシステムふがふが機能ぴよぴよ灰hネク惠比x? | × |
ぴよぴよ確認結果(NG) | ぴよぴよ確認結果(NG) | ○ |
あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほ | あいうえおかきくけこさしすせそたちつH,h,�,�,ィ,ク,ネ,リ--8-h | × |
アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲン | アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤm}狛ュスハmミ | × |
aaaaabbbbbcccccdddddeeeee | aaaaabbbbbcccccdddH(H(X(X(X(X(X( | × |
aaaaabbbbbccc...zzzzz | aaaaabbbbbccc...zzzzz | ○ |
結果
- 全角日本語
- 18文字目まで正常に表示
- 半角日本語
- 36文字目まで正常に表示
- 全角英字
- 18文字目まで正常に表示
- 半角英字
- 36文字を超えても正常に表示(130文字まで確認)
結論
下記のどれかで対応できそう
- 件名を短くする
- 件名を半角英字にする
- SwiftMailer以外の方法でメール送信を行う
もし「こうすれば長めの日本語件名にできるよ!」とか「ここ間違ってない?」とかあれば教えてください!