You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

wp_mail()发送附件后缀为.tmp的问题求助

解决WordPress REST API上传文件作为邮件附件时文件名显示临时.tmp的问题

你遇到的核心问题是PHP临时上传文件会在脚本执行完毕后自动删除,直接将tmp_name传给wp_mail,要么邮件附件显示为临时文件名,要么文件已被清理导致附件失效。要解决这个问题,需要先将临时文件复制到持久化临时目录,使用原始文件名,再作为附件发送,最后清理文件。

核心解决方案代码修改

替换你的prepare_attachments函数为以下代码:

protected function prepare_attachments($files) {
    $attachments = [];

    // 校验必要字段是否存在
    if (!isset($files['form_fields']['tmp_name']['file'], $files['form_fields']['name']['file'], $files['form_fields']['error']['file'])) {
        return $attachments;
    }

    $tmp_path = $files['form_fields']['tmp_name']['file'];
    $original_filename = $files['form_fields']['name']['file'];
    $upload_error = $files['form_fields']['error']['file'];

    // 检查上传是否成功
    if ($upload_error !== UPLOAD_ERR_OK) {
        error_log('文件上传错误代码: ' . $upload_error);
        return $attachments;
    }

    // 创建WordPress兼容的临时存储目录
    $temp_dir = WP_CONTENT_DIR . '/uploads/temp';
    if (!file_exists($temp_dir)) {
        wp_mkdir_p($temp_dir); // WordPress内置函数,自动处理目录权限
    }

    // 安全校验:验证文件类型合法性
    $file_type = wp_check_filetype($original_filename);
    if (empty($file_type['ext'])) {
        error_log('无效文件类型: ' . $original_filename);
        return $attachments;
    }

    // 生成安全的目标文件路径(使用原始文件名)
    $target_path = trailingslashit($temp_dir) . sanitize_file_name($original_filename);

    // 移动临时文件到目标路径(move_uploaded_file是PHP处理上传文件的安全方式)
    if (!move_uploaded_file($tmp_path, $target_path)) {
        error_log('无法移动上传文件: 源路径 ' . $tmp_path . ' → 目标路径 ' . $target_path);
        return $attachments;
    }

    // 将处理后的文件添加到附件列表
    $attachments[] = $target_path;

    // 注册脚本结束钩子,自动清理临时文件
    add_action('shutdown', function() use ($target_path) {
        if (file_exists($target_path)) {
            unlink($target_path);
        }
    });

    return $attachments;
}

关键改动说明

  • 持久化临时目录:使用wp_mkdir_p在wp-content/uploads下创建temp目录,确保目录权限符合WordPress安全标准,避免写入失败。
  • 安全校验:通过wp_check_filetype验证文件类型,sanitize_file_name处理原始文件名,防止恶意文件和非法字符导致的问题。
  • 文件移动:用move_uploaded_file替代直接引用临时文件,确保文件被复制到持久化位置,避免PHP自动删除临时文件导致附件失效。
  • 自动清理:通过shutdown钩子在脚本执行完毕后删除临时文件,避免服务器空间被垃圾文件占用。

额外检查项

  1. REST API权限:确保你的路由注册时设置了正确的permission_callback,比如:
    register_rest_route('my-plugin/v1', '/send_email/', [
        'methods' => 'POST',
        'callback' => [$this, 'handle_send_email'],
        'permission_callback' => function() {
            // 根据需求设置权限,比如允许所有用户提交表单
            return true;
            // 或者仅允许登录用户:return is_user_logged_in();
        }
    ]);
    
  2. PHP配置:检查php.ini中的upload_max_filesize和post_max_size参数,确保数值大于你允许上传的文件大小。

内容的提问来源于stack exchange,提问作者Lucas M. Falbo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 02:34:57