【Laravel】Laravel 内で送るメール全ての文字コードを UTF-8 と ISO-2022-JP で切り替える

 Laravel がラッピングしている Swift Mailer に全体に影響する設定を行う仕組みがあるのでそれを使います。設定変更クラスが次です。グローバルに設定をいじるのでお手軽シングルトンとして全て静的に記述しています。

<?php
/** /app/Mail/GlobalSwiftMailEncodeChanger.php */

namespace App\Mail;

use Swift_DependencyContainer;
use Swift_Preferences;

class GlobalSwiftMailEncodeChanger
{
    public const UTF8      = 'utf-8';
    public const ISO2022JP = 'iso-2022-jp';
    // 今どちらにセットされているかの目印。デフォルトは UTF8
    // ここの外部で設定されるとまったくあてにならなくなるので気休め
    protected static string $charset = self::UTF8;

    public static function getCurrentCharset(): string
    {
        return static::$charset;
    }

    /**
     * Laravel 内で送るメール(Swift Mailer で送られるメール)を ISO-2022-JP 形式に変更
     * @see https://swiftmailer.symfony.com/docs/japanese.html
     */
    public static function toIso2022Jp(): void
    {
        self::$charset = self::ISO2022JP;

        Swift_DependencyContainer::getInstance()
            ->register('mime.qpheaderencoder')
            ->asAliasOf('mime.base64headerencoder');

        Swift_Preferences::getInstance()->setCharset('iso-2022-jp');
    }

    /**
     * Laravel 内で送るメール(Swift Mailer で送られるメール)を UTF-8 形式に変更
     */
    public static function toUtf8(): void
    {
        self::$charset = self::UTF8;
        // ↑の toIso2022Jp メソッドで変更されるところを元々 UTF-8 で送れていた状態に復元する処理
        // 文字コード UTF-8 形式のメールを Quoted Printable 形式でエンコードする様に設定?いまいちよくわかっていない
        Swift_DependencyContainer::getInstance()
            ->register('mime.qpheaderencoder')
            ->addConstructorLookup('mime.charstream')
            ->asNewInstanceOf(\Swift_Mime_HeaderEncoder_QpHeaderEncoder::class);

        Swift_Preferences::getInstance()->setCharset('utf-8');
    }
}

 使用例としては次です。

<?php

namespace App\Http\Middleware;

use App\Mail\GlobalSwiftMailEncodeChanger;
use Closure;
use Illuminate\Http\Request;

class SetMailEncode
{
    public const KEY_IN_REQUEST = 'mailEncode';

    public function handle(Request $request, Closure $next)
    {
        // GET か POST で mailEncode=${文字コード} とパラメータを渡されたら、
        // そのリクエストの中の処理では渡された形式でメールを送るようにする
        $encode = $request->get(self::KEY_IN_REQUEST);
        $encode ??= $request->post(self::KEY_IN_REQUEST);
        // パラメータによって先述のメールの文字コードを変えるメソッドを呼び出す。
        $action = match ($encode) {
            'utf-8'       => static fn () => GlobalSwiftMailEncodeChanger::toUtf8(),
            'iso-2022-jp' => static fn () => GlobalSwiftMailEncodeChanger::toIso2022Jp(),
            default       => static fn () => null
        };
        $action();

        return $next($request);
    }
}

 こんな感じで比較的柔軟に Laravel 中のメールで使う文字コードを変えられます。

>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG