1. 導入
Webサイトのお問い合わせリンクなどでよく使われる「mailto:」ですが、件名や本文に日本語や改行を含めようとすると、メーラーによって正しく表示されなかったり、リンク自体が壊れて機能しなくなったりすることがあります。本稿では、PHPでURLエンコードを適切に行い、マルチバイト文字や改行を安全にmailtoリンクへ埋め込むための実務的な実装方法を解説します。
2. 基礎知識
URLの構造上、日本語などのマルチバイト文字や特殊記号はそのまま記述できません。これを解決するのが「URLエンコード」です。
PHPには主に「urlencode()」と「rawurlencode()」の2つがありますが、mailtoリンクで利用する場合は「rawurlencode()」を選択するのが正解です。
- urlencode(): スペースを「+」に変換(フォーム送信向け)。
- rawurlencode(): スペースを「%20」に変換(RFC 3986準拠。メールリンクにはこちらが適しています)。
また、複数のパラメータ(subjectやbodyなど)を扱う場合、手動で文字列結合をするとバグの温床になります。PHP標準の「http_build_query()」を利用することで、エンコードからクエリ文字列の組み立てまでを安全かつ効率的に行うことができます。
3. 実装/解決策
実務では、以下の手順で実装を行うのが最も安全です。
1. 本文内の改行コードを「\r\n」(CR+LF)に統一する(メーラー側の仕様に合わせるため)。
2. 「http_build_query()」の第4引数に「PHP_QUERY_RFC3986」を指定し、rawurlencode()相当の変換を適用する。
3. HTMLへの出力時に「&」を「&」としてエスケープする。
4. サンプルプログラム
以下のコードは、改行を含む本文を正しくmailtoリンクに変換する例です。
‘【お問い合わせ】件名が入ります’,
‘body’ => $formattedBody
], ”, ‘&’, PHP_QUERY_RFC3986);
?>
5. 応用・注意点
・メーラーの制限に注意
mailtoリンクはあくまでクライアント側のメーラーに依存する機能です。メーラーの設定やOSの仕様によっては、非常に長い文字列(数千文字を超えるような長文)は正しく展開されない場合があります。長文を送信させたい場合は、mailtoではなく、Webサーバー側で動作するフォーム送信(PHPのmail()関数やPHPMailer、Symfony Mailerなど)を利用するのが原則です。
・セキュリティの観点
ユーザー入力値をそのままsubjectやbodyに含める場合は、必ずXSS対策としてHTMLエスケープを忘れないでください。上記サンプルではhref属性内での出力となるため、属性値として安全な形式になっているか、運用環境に合わせて再確認することをお勧めします。