使用filter_var(FILTER_SANITIZE_EMAIL)时如何保留表单文本域换行符?
问题分析
你遇到的核心问题是错误使用了FILTER_SANITIZE_EMAIL过滤器——这个过滤器的设计目标是清理邮箱地址字符串,会移除所有不属于邮箱允许范围的字符(包括换行符\n、\r),所以多行地址的换行被直接过滤掉,导致内容拼接在一起。
解决方案
要保留换行并安全清理地址文本,需要换用适合处理普通文本的过滤方式,同时统一换行符格式以适配邮件系统:
步骤1:选择合适的文本清理方式
放弃FILTER_SANITIZE_EMAIL,改用以下两种安全的清理方式之一:
- 方式一:使用
FILTER_SANITIZE_FULL_SPECIAL_CHARS:等价于htmlspecialchars(),会转义HTML特殊字符(防止注入风险),同时保留换行、空格等普通文本格式。 - 方式二:手动结合
trim()和htmlspecialchars():更灵活,适合需要额外处理的场景。
步骤2:统一换行符格式
用户输入的换行符可能因系统不同而不同(Windows是\r\n,Linux是\n,旧版Mac是\r),需要统一转换为邮件系统能识别的换行格式(纯文本邮件用\n或PHP_EOL均可)。
修改后的代码示例
示例1:使用filter_var的安全文本过滤
// 获取并清理地址文本,保留换行 $clean_addr = filter_var($_POST['addr'], FILTER_SANITIZE_FULL_SPECIAL_CHARS); // 统一换行符为\n $formatted_addr = str_replace(["\r\n", "\r"], "\n", $clean_addr); // 拼接邮件正文,用PHP_EOL保证跨平台换行 $em_body = 'Address:' . PHP_EOL . $formatted_addr;
示例2:手动清理(更灵活)
// 先去除首尾空白,再转义特殊字符 $addr = trim($_POST['addr']); $clean_addr = htmlspecialchars($addr, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); // 统一换行符 $formatted_addr = str_replace(["\r\n", "\r"], "\n", $clean_addr); // 拼接邮件正文 $em_body = 'Address:' . PHP_EOL . $formatted_addr;
额外注意事项
- 如果你发送的是HTML格式邮件,需要把换行符转换为
<br>标签,同时确保清理后的文本不会被解析为HTML:$formatted_addr = nl2br(htmlspecialchars($addr, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8')); - 永远不要信任用户输入,即使是地址文本,也要通过转义或过滤避免恶意代码注入(比如邮件头注入)。
内容的提问来源于stack exchange,提问作者1337ingDisorder
相关产品推荐
相关产品推荐

