WordPress REST API发送带附件邮件报错求助
问题:WordPress REST API发送带附件邮件触发类型错误
尝试通过WordPress REST API接收前端上传的文件并发送邮件,能正常获取表单数据和文件信息,但无法将文件附加到邮件,触发以下致命错误:
Fatal error: Uncaught TypeError: preg_match(): Argument #2 ($subject) must be of type string, array given in /var/www/html/wp-includes/PHPMailer/PHPMailer.php:1853 Stack trace: #0 /var/www/html/wp-includes/PHPMailer/PHPMailer.php(1853): preg_match('#^[a-z][a-z\d+....', Array) #1 /var/www/html/wp-includes/PHPMailer/PHPMailer.php(1865): PHPMailer\PHPMailer\PHPMailer::isPermittedPath(Array) #2 /var/www/html/wp-includes/PHPMailer/PHPMailer.php(3193): PHPMailer\PHPMailer\PHPMailer::fileIsAccessible(Array) #3 /var/www/html/wp-includes/pluggable.php(522): PHPMailer\PHPMailer\PHPMailer->addAttachment(Array) #4 /var/www/html/wp-content/plugins/my-project/views/API/email.php(100): wp_mail(Array, 'Demande de fina...', ' <h1>Demande d...', Array, Array) #5 /var/www/html/wp-includes/rest-api/class-wp-rest-server.php(1171): financement_email(Object(WP_REST_Request)) #6 /var/www/html/wp-includes/rest-api/class-wp-rest-server.php(1018): WP_REST_Server->respond_to_request(Object(WP_REST_Request), '/my-project/fin...', Array, NULL) #7 /var/www/html/wp-includes/rest-api/class-wp-rest-server.php(442): WP_REST_Server->dispatch(Object(WP_REST_Request)) #8 /var/www/html/wp-includes/rest-api.php(410): WP_REST_Server->serve_request('/my-project/fin...') #9 /var/www/html/wp-includes/class-wp-hook.php(308): rest_api_loaded(Object(WP)) #10 /var/www/html/wp-includes/class-wp-hook.php(332): WP_Hook->apply_filters('', Array) #11 /var/www/html/wp-includes/plugin.php(565): WP_Hook->do_action(Array) #12 /var/www/html/wp-includes/class-wp.php(399): do_action_ref_array('parse_request', Array) #13 /var/www/html/wp-includes/class-wp.php(780): WP->parse_request('') #14 /var/www/html/wp-includes/functions.php(1332): WP->main('') #15 /var/www/html/wp-blog-header.php(16): wp() #16 /var/www/html/index.php(17): require('/var/www/html/w...') #17 {main} thrown in /var/www/html/wp-includes/PHPMailer/PHPMailer.php on line 1853
当前使用的代码:
获取文件参数:
$files = $request->get_file_params();
调用wp_mail:
wp_mail( $to, $subject, $body, $headers, $files)
解决方案
问题根源
$request->get_file_params()返回的是类似$_FILES的数组结构,每个文件元素是包含tmp_name(临时文件路径)、name(原文件名)、size等字段的数组。而wp_mail的第5个参数(附件)需要的是文件路径字符串数组,或者是[文件路径 => 自定义文件名]的关联数组。直接传入$files会导致PHPMailer接收到数组而非字符串路径,触发类型错误。
修正代码
需要遍历文件参数,提取临时文件路径并整理成wp_mail要求的格式:
方式1:直接使用临时文件(请求结束后会被系统删除)
$files = $request->get_file_params(); $attachments = []; foreach ($files as $file) { // 验证临时文件是否合法上传 if (isset($file['tmp_name']) && is_uploaded_file($file['tmp_name'])) { // 关联数组格式:键为临时文件路径,值为原文件名(邮件中显示的文件名) $attachments[$file['tmp_name']] = $file['name']; // 若不需要自定义文件名,直接添加路径即可: // $attachments[] = $file['tmp_name']; } } // 调用wp_mail时传入处理后的附件数组 wp_mail($to, $subject, $body, $headers, $attachments);
方式2:保留上传文件到WordPress目录(推荐)
临时文件会在请求结束后被系统删除,如果需要长期保留文件,先使用wp_handle_upload将文件移动到WordPress上传目录,再使用新路径作为附件:
$files = $request->get_file_params(); $attachments = []; foreach ($files as $file) { if (isset($file['tmp_name']) && is_uploaded_file($file['tmp_name'])) { // 处理上传,禁用表单验证(因为是REST API上传,不是常规表单) $upload = wp_handle_upload($file, ['test_form' => false]); if (!isset($upload['error'])) { // 添加上传后的文件路径到附件数组 $attachments[] = $upload['file']; } } } wp_mail($to, $subject, $body, $headers, $attachments);
内容的提问来源于stack exchange,提问作者n3tx
相关产品推荐
相关产品推荐

