如何在 PHP 中精准查找并替换 Unicode 乘号(×)字符

本文详解如何在 php 中安全、准确地识别并替换 stripe webhook 返回的 utf-8 乘号“×”(u+00d7),避免因编码不一致导致邮件中显示为乱码“a”,提供多种兼容写法及实用注意事项。

在处理 Stripe 等第三方服务返回的 JSON 数据时,其 description 字段常包含 Unicode 格式的乘号 ×(U+00D7),例如:
"1 × Base Package (at $25.00 / year)"

该字符在 UTF-8 编码下实际为字节序列 \xc3\x97(对应 Unicode 码点 \u{d7}),但若系统未正确声明或处理 UTF-8 上下文(如邮件头部缺失 Content-Type: text/plain; charset=utf-8),该字符极易被错误解码为 Ã 或 A,造成显示异常。

最直接可靠的解决方案是使用 PHP 原生的 str_replace() 函数——它完全二进制安全,无需额外启用 mbstring 扩展即可精准匹配并替换 Unicode 字符:

$string = "1 × Base Package (at $25.00 / year)";
$cleanString = str_replace('×', 'x', $string);
// 输出: "1 x Base Package (at $25.00 / year)"

为提升代码可读性与可维护性,推荐以下三种等效写法(任选其一):

推荐:直观 Unicode 字符字面量(需确保 PHP 文件保存为 UTF-8 编码)

$cleanString = str_replace('×', 'x', $string);

显式 Unicode 转义(PHP 7.0+ 支持,语义清晰,不依赖文件编码)

$cleanString = str_replace("\u{d7}", 'x', $string); // 推荐用于团队协作项目

UTF-8 字节序列写法(兼容所有 PHP 版本,适合严格环境)

$cleanString = str_replace("\xc3\x97", 'x', $string);

⚠️ 重要注意事项:

  • ✅ str_replace() 是二进制安全的,无需 mb_ 系列函数,性能更优;
  • ❌ 避免使用 preg_replace() 配合 /u 修饰符进行单字符替换——过度设计且易引入 PCRE 编码陷阱;
  • ? 发送邮件时务必设置正确的 HTTP/SMTP 头部:
    // HTML 邮件示例
    $headers = "Content-Type: text/html; charset=utf-8\r\n";
    // 或纯文本邮件
    $headers = "Content-Type: text/plain; charset=utf-8\r\n";
  • ? 若需批量处理多个特殊符号(如 —、–、…),建议构建映射数组统一替换:
    $replacements = [
        '×' => 'x',
        '—' => '--',
        '–' => '-',
        '…' => '...',
    ];
    $cleanString = str_replace(array_keys($replacements), array_values($replacements), $string);

综上,针对 Stripe Webhook 中的 × 字符,采用 str_replace('×', 'x', $str) 是最简洁、高效、健壮的实践方案。关键在于确保开发环境、源码文件、HTTP 响应及邮件传输全程统一使用 UTF-8 编码,从根源杜绝乱码问题。