需用file_get_contents("php://input")读取原始XML数据,再用simplexml_load_string或DOMDocument解析;旧版PHP可兼容$HTTP_RAW_POST_DATA;若需验签,应提取HTTP头签名并与原始XML体比对。

如果您在开发PHP应用时需要接收外部系统推送的XML格式实时数据,则可能是由于客户端通过HTTP POST方式将XML内容发送至PHP脚本。以下是实现此功能的几种常用方式:
一、使用file_get_contents("php://input")读取原始输入流
PHP默认不会自动解析XML格式的POST数据,当Content-Type为application/xml或text/xml时,$_POST为空,必须直接读取原始请求体。
1、确保PHP脚本位于可被外部HTTP请求访问的路径下,例如receive.php。
2、在脚本开头添加header设置,防止编码问题:header('Content-Type: text/plain; charset=utf-8');
立即学习“PHP免费学习笔记(深入)”;
3、调用file_get_contents("php://input")获取完整XML字符串:$xmlString = file_get_contents("php://input");
4、检查字符串是否为空:if (empty($xmlString)) { die("No XML data received"); }
5、使用simplexml_load_string()解析XML:$xml = simplexml_load_string($xmlString, 'SimpleXMLElement', LIBXML_NOCDATA);
二、使用$HTTP_RAW_POST_DATA(已弃用但部分旧环境仍需兼容)
在PHP 5.6及更早版本中,若启用always_populate_raw_post_data指令,可通过该超全局变量获取原始POST数据,但自PHP 7.0起已被移除,仅作兼容性说明。
1、确认PHP版本低于7.0且php.ini中设置always_populate_raw_post_data = -1。
2、直接访问变量:$xmlString = $HTTP_RAW_POST_DATA;
3、验证数据有效性:if ($xmlString === false || trim($xmlString) === '') { exit('Invalid raw POST data'); }
4、加载为SimpleXML对象:$xml = simplexml_load_string($xmlString);
三、通过cURL模拟接收并验证XML签名
某些实时数据接口要求接收方校验数字签名,此时需在接收后立即提取签名头并与XML体计算比对。
1、从HTTP请求头中读取签名字段:$signature = $_SERVER['HTTP_X_SIGNATURE'] ?? '';
2、获取原始XML数据:$xmlRaw = file_get_contents('php://input');
3、使用约定密钥与哈希算法(如HMAC-SHA256)重新生成签名:$expected = hash_hmac('sha256', $xmlRaw, 'your_shared_secret');
4、严格比较签名:if (!hash_equals($expected, $signature)) { http_response_code(401); exit('Signature mismatch'); }
四、使用DOMDocument进行结构化解析与容错处理
当接收到的XML可能包含命名空间、特殊字符或格式不规范时,DOMDocument比SimpleXML更具可控性和错误捕获能力。
1、初始化DOMDocument实例:$dom = new DOMDocument();
2、关闭内部错误报告以避免警告干扰:$dom->preserveWhiteSpace = false;
3、加载XML字符串并启用libxml错误处理:$dom->loadXML($xmlRaw, LIBXML_NOERROR | LIBXML_NOWARNING);
4、检查加载是否成功:if ($dom->parseError->error_code !== 0) { throw new Exception('XML parsing failed: ' . $dom->parseError->message); }
5、按标签名提取节点:$nodes = $dom->getElementsByTagName('item');











