PHP处理XML请求体需读取php://input流并解析:用file_get_contents或fopen获取原始数据,simplexml_load_string或DOMDocument解析;校验Content-Type与编码;弃用$HTTP_RAW_POST_DATA;可用cURL测试。

如果您在开发PHP接口时需要处理客户端发送的XML格式请求体,则必须正确读取原始输入流并解析XML内容。以下是实现该功能的具体方法:
一、使用file_get_contents读取php://input
PHP无法通过$_POST直接获取XML请求体,因为XML不是标准的application/x-www-form-urlencoded或multipart/form-data编码格式。必须从php://input流中读取原始数据,再用XML解析器处理。
1、使用file_get_contents('php://input')获取原始XML字符串。
2、检查返回值是否为空,若为空则说明未收到有效XML数据。
立即学习“PHP免费学习笔记(深入)”;
3、使用simplexml_load_string()将XML字符串转换为SimpleXMLElement对象。
4、若解析失败,可使用libxml_use_internal_errors(true)捕获错误并调试。
二、使用fopen读取php://input流
当XML体积较大或需分块处理时,fopen方式更可控,避免内存一次性加载全部内容,适用于对资源占用敏感的场景。
1、调用fopen('php://input', 'rb')以二进制只读模式打开输入流。
2、使用stream_get_contents()读取全部内容,或配合fgets()逐行读取。
3、关闭文件指针,防止资源泄漏。
4、将读取结果传入DOMDocument::loadXML()进行解析。
三、使用$HTTP_RAW_POST_DATA(已弃用但需兼容旧环境)
在PHP 5.6及更早版本且配置中启用always_populate_raw_post_data时,$HTTP_RAW_POST_DATA变量可能包含原始POST数据。该方式不推荐用于新项目,但在维护遗留系统时可能遇到。
1、检查$HTTP_RAW_POST_DATA是否存在且非空。
2、若存在,直接将其作为XML字符串处理。
3、若不存在,回退至php://input读取逻辑。
4、注意在PHP 7.0+中该变量已被移除,必须禁用此分支。
四、设置Content-Type校验与编码处理
接收XML前应验证请求头中的Content-Type是否为text/xml、application/xml或application/xhtml+xml,防止非法格式注入;同时需处理XML声明中的encoding属性,确保字符解码正确。
1、通过getallheaders()或$_SERVER['CONTENT_TYPE']获取请求头中的类型信息。
2、使用mb_detect_encoding()或simplexml_load_string()内部机制判断编码。
3、若XML声明指定UTF-8但实际为GB2312,需先用mb_convert_encoding()转码。
4、校验失败时返回HTTP 415 Unsupported Media Type状态码。
五、使用cURL模拟XML请求进行本地测试
在开发阶段需验证PHP端能否正确接收并解析XML,可通过cURL构造标准XML POST请求,确认服务端逻辑无误。
1、准备XML字符串,确保格式良好且包含XML声明。
2、使用curl_init()初始化句柄,设置CURLOPT_URL为目标地址。
3、设置CURLOPT_POSTFIELDS为XML字符串,CURLOPT_HTTPHEADER为['Content-Type: application/xml']。
4、执行请求后检查响应内容是否包含预期解析结果或错误提示。











