不能。WordPress REST API 默认不支持application/xml,需手动注册端点读取php://input并解析XML,注意Content-Type校验、空白处理、异常捕获及数据过滤。

WordPress REST API 能否直接接收 XML 文件?
不能。WordPress REST API 默认只接受 application/json 或表单编码(application/x-www-form-urlencoded、multipart/form-data)的请求体,application/xml 不在默认解析支持范围内。即使你用 curl 发送 XML,$_POST 和 $_REQUEST 仍为空,file_get_contents('php://input') 才是唯一可靠入口。
如何注册一个能读取原始 XML 的自定义 REST 端点?
必须绕过 WordPress 的默认参数解析逻辑,手动读取原始请求体,并在回调函数中解析 XML。关键点:注册端点时设 methods 为 WP_REST_Server::CREATABLE,禁用 args 参数校验(否则会因无法匹配 JSON schema 报错),并在回调里用 file_get_contents('php://input') 拿到原始字节。
-
register_rest_route()的args数组不要定义任何参数字段,否则 REST 服务器会尝试自动解析并失败 - 务必检查
Content-Type请求头是否为application/xml或text/xml,避免误处理其他类型 - 使用
simplexml_load_string()解析前,先用trim()去除空白,否则空字符串会导致警告 - 捕获
SimpleXMLElement构造异常,返回有意义的WP_Error
register_rest_route('myplugin/v1', '/upload-xml', array(
'methods' => WP_REST_Server::CREATABLE,
'callback' => function( $request ) {
$raw_body = file_get_contents('php://input');
if ( ! $raw_body ) {
return new WP_Error('empty_body', 'No XML data received', array('status' => 400));
}
$content_type = $request->get_header('Content-Type');
if ( false === stripos($content_type, 'application/xml') && false === stripos($content_type, 'text/xml') ) {
return new WP_Error('invalid_content_type', 'Content-Type must be application/xml or text/xml', array('status' => 400));
}
$xml = simplexml_load_string(trim($raw_body));
if ( false === $xml ) {
return new WP_Error('invalid_xml', 'Failed to parse XML', array('status' => 400));
}
// 此处处理 $xml 对象,例如:$xml->item->__toString()
return rest_ensure_response(array('status' => 'success', 'parsed' => true));
},
'permission_callback' => '__return_true', // 实际使用请替换为真实权限检查
));
XML 解析后如何安全提取数据并存入数据库?
不要直接将 SimpleXMLElement 对象传给 $wpdb->insert() 或 wp_insert_post()。XML 节点名可能含非法字符,文本值可能含未转义 HTML 或恶意脚本。必须显式遍历、过滤、验证每个字段。
- 用
(string) $xml->field_name强制转为字符串,避免对象残留 - 对用户输入字段(如标题、内容)使用
wp_kses_post()或sanitize_text_field(),而非esc_html()(后者是输出函数) - 数值字段用
absint()或floatval()显式转换,防止字符串注入 - 如果 XML 含嵌套结构(如
),需用- ...
foreach( $xml->items->item as $item )遍历,不能假设只有一项
为什么用 multipart/form-data 上传 XML 文件更稳妥?
直接 POST XML 字符串容易因编码(如 UTF-8 BOM)、换行符、特殊字符(, &)导致解析失败;而用文件上传方式,XML 作为二进制附件传输,服务端从 $_FILES 读取,规避了 HTTP 主体解析问题。此时端点应接受 multipart/form-data,并用 move_uploaded_file() 临时保存再解析。
-
前端用
FormData.append('xml_file', fileInput.files[0])提交 -
后端检查
$_FILES['xml_file']['error'] === UPLOAD_ERR_OK再处理 - 临时文件路径用
$_FILES['xml_file']['tmp_name'],解析完立即unlink() - 务必限制
$_FILES['xml_file']['size'](如 ≤ 2MB),防止 DoS
真正麻烦的不是注册端点,而是 XML 的编码一致性、实体转义、命名空间处理和错误定位——这些全得自己兜底,REST API 不提供 XML Schema 验证或自动映射。









