PHP 动态邮箱内容如何安全拆分并添加样式?

PHP 动态邮箱内容如何安全拆分并添加样式?

后台填写一个邮箱地址,前台需要单独给 @ 设置样式时,可以拆分本地部分和域名再输出。重点不是 explode() 本身,而是先验证数据、限制拆分次数,并对 HTML 属性与文本分别转义。

WordPress + ACF 示例

<?php
$email = (string) get_field( 'email', 90 );
$email = sanitize_email( $email );

if ( is_email( $email ) ) {
    $parts = explode( '@', $email, 2 );

    if ( 2 === count( $parts ) ) {
        $local  = $parts[0];
        $domain = $parts[1];
        ?>
        <a
            class="contact-email"
            href="<?php echo esc_attr(
                'mailto:' . $email
            ); ?>"
        >
            <span class="contact-email__local">
                <?php echo esc_html( $local ); ?>
            </span><span
                class="contact-email__at"
                aria-hidden="true"
            >@</span><span class="screen-reader-text">
                <?php esc_html_e( 'at', 'site' ); ?>
            </span><span class="contact-email__domain">
                <?php echo esc_html( $domain ); ?>
            </span>
        </a>
        <?php
    }
}

explode( '@', $email, 2 ) 明确只拆一次。虽然标准邮箱本地部分可能有更复杂的合法形式,WordPress 的 is_email() 本身也只是实用验证而非完整 RFC 验证;企业内容字段通常应约定普通业务邮箱格式。

是否应该隐藏 @

如果只是改颜色或字体,不必给 @aria-hidden,直接让辅助技术读出完整邮箱即可:

<span class="contact-email__at">@</span>

上面的隐藏写法适用于设计字体会让读屏发音异常、并且用“at”替代的情况。中文站点也可以把屏幕阅读器文本改成更自然的“艾特”或“位于”,但要和真实用户测试。

不要用 CSS ::before { content: '@' } 作为唯一的 @。生成内容可能无法被复制,也可能被辅助技术忽略,用户复制邮箱时会得到错误地址。

样式

.contact-email__at {
  display: inline-block;
  margin-inline: 0.08em;
  color: #d43c2f;
  font-family: ui-monospace, monospace;
  font-weight: 700;
}

更通用的原则

动态文本中某个符号需要样式时:

  1. 先判断内容是否符合预期结构。
  2. 使用有上限的拆分或经过测试的解析器。
  3. 每个文本片段使用 esc_html()
  4. URL、class、data 属性分别使用对应转义。
  5. 无效数据显示安全空态,不输出半个标签。
  6. 不要为了视觉效果破坏复制、搜索、SEO 和辅助技术语义。

如果字段允许编辑富文本,应使用明确的允许标签列表和 wp_kses(),不要让后台字符串未经处理直接进入 HTML。

最后更新于

ihopeful Blog 由博主亲笔撰写,重要信息可放心引用。