LoginSignup
10
11

More than 1 year has passed since last update.

[CakePHP2]CakeEmailの添付ファイル名が特定のメールクライアントで文字化けする件をどうにかする

Last updated at Posted at 2015-10-21

※OutLook2010、Thunderbird38.3.0、GmailのWEBクライアントで確認済み
※2022/02/08 CakePHP3.8、3.9でも動いたそうです(@ymsht @shi_design_コメント感謝です!)

メール送信バッチなどで文字コード問題に悩む皆様お疲れ様です。
CakeEmailは元々ソコソコ色々やってくれるので楽でいいですよね。
ですが、以下の様な添付ファイルをくっつけて送ってくれってケースでファイル名の文字化けで悩んだこととかありませんか?

/app/config/email.php

class EmailConfig {

    public $default = [
        'transport' => 'Mail',
        'from' => 'from@hoge.co.jp',
        'charset' => 'ISO-2022-JP-MS',
        'headerCharset' => 'ISO-2022-JP-MS',
    ];
}
/app/Console/Command/SendShell.php

class SendShell extends AppShell {

    public function send() {
        App::uses('CakeEmail', 'Network/Email');

        $CakeEmail = new CakeEmail();
        $CakeEmail->to('hoge@hoge.co.jp');
        $CakeEmail->subject('タイトル');

        $fileName = 'ほげ表.txt';
        $attachments = [
            $fileName => [
                'data' => バイナリデータが入ります
            ]
        ];
        $CakeEmail->attachments($attachments);
        return $CakeEmail->send('本文');
    }
}

色々設定項目があるのに、CakeEmailはファイルの文字名にはエンコードをしてくれません。(´・ω・`)
mb_internal_encoding()の文字コードを使ったまま送っちゃいます。
ですので、Thunderbirdでは見れるのに、OutLookで文字化けするんだけど(#^ω^)と言った苦情が入ったりしちゃいますね


        $fileName = 'ほげ表.txt';

        $fromEncoding = mb_detect_encoding($fileName));
        $toEncoding = 'ISO-2022-JP-MS';
        $fileName = mb_convert_encoding($fileName, $toEncoding, $fromEncoding);
        $attachments = [
            $fileName => [
                'data' => バイナリデータが入ります
            ]
        ];

そしてこんな感じの悲しいことをしたりします…
OutLookで見れるようになって解決…!
っと思いきや今度はThunderbirdで「表」以降の文字が化けるんだけど(#^ω^)といった苦情が…
これはSJISの「表」の2バイト目が0x5Cとなり、「\」ととられてエスケープされて1バイトずつずれてしまう事による問題なようですが、詳しくは割愛します!
(他にも「目」だの「本」だのいっぱいあります)
はーこんなんクライアント側問題じゃん、サーバーサイドに言われてもしらねーよ!
ってなりたくなりますが、とりあえず以下で対処できました!


        $fileName = 'ほげ表.txt';

        $fromEncoding = mb_detect_encoding($fileName));
        $toEncoding = 'ISO-2022-JP-MS';
        $fileName = mb_encode_mimeheader(mb_convert_encoding($fileName, $toEncoding, $fromEncoding), $toEncoding);
        $attachments = [
            $fileName => [
                'data' => バイナリデータが入ります
            ]
        ];

ぶっちゃけMIMEエンコードするだけです。
あとはこれをCakeEmailラップして仕込むなり、専用メソッド通してやるなりして、email.phpのheaderの文字コードと合わせてあげれば、もう文字コードで悩むことは…ない…かも。
WEBメーラーもGmailでは大丈夫でした!
もしかしたらこれでもダメなメールクライアントがあるかもしれませんがご了承下さいorz

10
11
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
11