PHPMailer发送dompdf生成的阿拉伯语PDF出现文件名前缀丢失如何解决
问题解决方案
该问题根源为PHP原生basename()函数对阿拉伯语这类RTL(从右到左书写)的UTF-8字符支持缺陷:该函数依赖服务器的区域(locale)配置,若未安装对应语言的UTF-8语言包,会将非ASCII开头的字符串前缀误判为路径部分丢弃。
通用修复:替换原生basename()为UTF-8兼容实现
该方案不受服务器环境限制,适配所有UTF-8字符场景,自定义函数如下:
function utf8_basename($path, $suffix = '') { // 移除路径末尾的分隔符 $path = rtrim($path, '/\\'); // 按路径分隔符拆分字符串取最后一段 $pathParts = preg_split('~[\\\\/]~', $path); $fileName = array_pop($pathParts); // 处理指定后缀的移除逻辑 if ($suffix !== '' && substr($fileName, -strlen($suffix)) === $suffix) { $fileName = substr($fileName, 0, -strlen($suffix)); } return $fileName; }
测试echo utf8_basename('محمد احمد علي');即可返回完整的原字符串,不会丢失前缀。
适配Dompdf下载场景
如果你需要调用Dompdf的stream()方法直接下载PDF,可二选一处理:
- 改Dompdf源码:搜索源码中调用
basename()的位置(一般在src/Dompdf.php的stream()方法或者PDF渲染适配器文件中),替换为上面的utf8_basename()函数即可。 - 自定义输出逻辑:不使用Dompdf自带的
stream()方法,自己手动输出HTTP头下载,避开内部的basename()调用:
$pdfContent = $dompdf->output(); $fileName = 'محمد_احمد_علي.pdf'; header('Content-Type: application/pdf'); header('Content-Disposition: attachment; filename*=UTF-8\'\'' . rawurlencode($fileName)); header('Content-Length: ' . strlen($pdfContent)); echo $pdfContent; exit;
适配PHPMailer发件场景
确保PHPMailer正确识别UTF-8编码的文件名,调用附件方法时按如下格式传参即可:
$name = 'محمد احمد علي'; $pdfName = str_replace(" ", "_", $name) . ".pdf"; // 传入编码和文件类型参数,PHPMailer会自动处理UTF-8文件名的编码兼容 $mail->addStringAttachment( $pdf, $pdfName, PHPMailer\PHPMailer\PHPMailer::ENCODING_BASE64, 'application/pdf' );
如果部分老旧邮件客户端仍显示异常,可手动对文件名进行编码后传入:
$pdfName = '=?UTF-8?B?' . base64_encode($pdfName) . '?=';
内容的提问来源于stack exchange,提问作者user_411
相关产品推荐
相关产品推荐

