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

如何在PHP中读取传入的SOAP请求?问题排查与示例需求

处理SOAP请求读取问题的解决方案

问题概述

现有如下SOAP请求:

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
    <soapenv:Body>
        <tem:ApplyTransactionRequest xmlns:tem="http://tempuri.org/"
xmlns:at="http://cps.huawei.com/cpsinterface/goa/at"
xmlns:goa="http://cps.huawei.com/cpsinterface/goa">
            <at:Header>
                <goa:CommandID>CheckInformation</goa:CommandID>
                <goa:Version>1.0</goa:Version>
                <goa:LoginID>NGOLoanPay</goa:LoginID>
                <goa:Password>e7L/g2/isbOu5Q6fHW3CAYtWgGYv8Av64BQet3WBQpmraV3HTzvlMBdQzGx056gY</goa:Password>
                <goa:Timestamp>20220110111810</goa:Timestamp>
                <goa:ConversationID>9DJ906XRUD</goa:ConversationID>
                <goa:HeaderExtension>
                    <goa:Parameter>
                        <goa:Key>name</goa:Key>
                        <goa:Value>cps</goa:Value>
                    </goa:Parameter>
                </goa:HeaderExtension>
            </at:Header>
            <at:Body>
                <at:Parameters>
                    <goa:Parameter>
                        <goa:Key>IDNumber</goa:Key>
                        <goa:Value>220214000126</goa:Value>
                    </goa:Parameter>
                    <goa:Parameter>
                        <goa:Key>FullName</goa:Key>
                        <goa:Value>MAYA</goa:Value>
                    </goa:Parameter>
                    <goa:Parameter>
                        <goa:Key>InquiryType</goa:Key>
                        <goa:Value>01</goa:Value>
                    </goa:Parameter>
                    <goa:Parameter>
                        <goa:Key>InquiryMode</goa:Key>
                        <goa:Value>02</goa:Value>
                    </goa:Parameter>
                    <goa:Parameter>
                        <goa:Key>FirstName</goa:Key>
                        <goa:Value></goa:Value>
                    </goa:Parameter>
                    <goa:Parameter>
                        <goa:Key>InitiatorID</goa:Key>
                        <goa:Value>8801301712997</goa:Value>
                    </goa:Parameter>
                    <goa:Parameter>
                        <goa:Key>ChannelCode</goa:Key>
                        <goa:Value>10</goa:Value>
                    </goa:Parameter>
                     <goa:Parameter>
                        <goa:Key>channelCode</goa:Key>
                        <goa:Value>10</goa:Value>
                    </goa:Parameter>
                    <goa:Parameter>
                        <goa:Key>LastName</goa:Key>
                        <goa:Value></goa:Value>
                    </goa:Parameter>
                    <goa:Parameter>
                        <goa:Key>PartnerID</goa:Key>
                        <goa:Value>MFI</goa:Value>
                    </goa:Parameter>
                    <goa:Parameter>
                        <goa:Key>ChkAmount</goa:Key>
                        <goa:Value></goa:Value>
                    </goa:Parameter>
                    <goa:Parameter>
                        <goa:Key>EndMonth</goa:Key>
                        <goa:Value></goa:Value>
                    </goa:Parameter>
                    <goa:Parameter>
                        <goa:Key>ExtendedParmeter1</goa:Key>
                        <goa:Value></goa:Value>
                    </goa:Parameter>
                    <goa:Parameter>
                        <goa:Key>SubID</goa:Key>
                        <goa:Value></goa:Value>
                    </goa:Parameter>
                    <goa:Parameter>
                        <goa:Key>AccountID</goa:Key>
                        <goa:Value>201004000589</goa:Value>
                    </goa:Parameter>
                    <goa:Parameter>
                        <goa:Key>StartMonth</goa:Key>
                        <goa:Value></goa:Value>
                    </goa:Parameter>
                </at:Parameters>
            </at:Body>
        </tem:ApplyTransactionRequest>
    </soapenv:Body>
</soapenv:Envelope>

尝试用以下代码读取请求,但无法正常获取内容:

function CheckInfoAPI()
{
        $soap_request = file_get_contents("php://input");
        $parser=xml_parser_create();
        xml_parse_into_struct($parser,$soap_request,$request_array);
        xml_parser_free($parser);
        var_dump($parser); 
    }

执行后返回:

resource(49) of type (Unknown)

需要解决如何获取请求中的LoginID、Password等字段,实现根据不同用户返回不同响应。

代码问题分析

  • 调用xml_parser_free($parser)后,XML解析器资源已被释放,此时再var_dump($parser)自然会显示Unknown类型的资源,属于无效操作。
  • 实际解析结果存储在$request_array变量中,但代码未对其进行处理;而且原生XML解析函数处理带命名空间的SOAP请求会非常繁琐,容易出错。

推荐解决方案:使用SimpleXML处理带命名空间的SOAP请求

PHP的SimpleXML扩展可以更便捷地处理带命名空间的XML,以下是适配该SOAP请求的完整示例:

function CheckInfoAPI()
{
    // 读取SOAP请求内容
    $soapRequest = file_get_contents("php://input");
    
    // 加载XML内容
    $xml = simplexml_load_string($soapRequest);
    
    // 注册SOAP请求中用到的命名空间
    $xml->registerXPathNamespace('soapenv', 'http://www.w3.org/2003/05/soap-envelope');
    $xml->registerXPathNamespace('tem', 'http://tempuri.org/');
    $xml->registerXPathNamespace('at', 'http://cps.huawei.com/cpsinterface/goa/at');
    $xml->registerXPathNamespace('goa', 'http://cps.huawei.com/cpsinterface/goa');
    
    // 获取Header中的LoginID和Password
    $loginId = (string)$xml->xpath('//goa:LoginID')[0];
    $password = (string)$xml->xpath('//goa:Password')[0];
    
    // 获取其他Header字段
    $commandId = (string)$xml->xpath('//goa:CommandID')[0];
    $timestamp = (string)$xml->xpath('//goa:Timestamp')[0];
    
    // 解析Parameters中的键值对为关联数组
    $parameters = [];
    $paramNodes = $xml->xpath('//goa:Parameter');
    foreach ($paramNodes as $node) {
        $key = (string)$node->Key;
        $value = (string)$node->Value;
        $parameters[$key] = $value;
    }
    
    // 根据LoginID等信息生成对应的响应
    $responseContent = match ($loginId) {
        'NGOLoanPay' => '验证通过,返回用户专属数据',
        default => '未知用户,返回默认响应'
    };
    
    // 输出SOAP响应(复用已有响应生成逻辑)
    generateSoapResponse($responseContent);
    
    // 调试用:输出获取到的数据
    // var_dump($loginId, $password, $parameters);
}

// 模拟已有的响应生成函数
function generateSoapResponse($content) {
    header('Content-Type: application/soap+xml; charset=utf-8');
    echo '<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
        <soapenv:Body>
            <tem:ApplyTransactionResponse xmlns:tem="http://tempuri.org/">
                <Result>'.$content.'</Result>
            </tem:ApplyTransactionResponse>
        </soapenv:Body>
    </soapenv:Envelope>';
}

代码说明

  1. 读取请求:通过file_get_contents("php://input")获取原始SOAP请求内容。
  2. 加载XML:使用simplexml_load_string将XML字符串转换为SimpleXMLElement对象。
  3. 注册命名空间:由于SOAP请求包含多个命名空间,需要通过registerXPathNamespace注册后,才能用XPath精准定位节点。
  4. 提取字段:通过XPath表达式定位LoginID、Password等节点,转换为字符串类型获取值。
  5. 解析参数:遍历所有goa:Parameter节点,将键值对整理为关联数组,方便后续使用。
  6. 生成响应:根据获取到的用户信息(如LoginID)生成对应的SOAP响应。

备选方案:使用PHP SOAP扩展

如果服务器启用了PHP SOAP扩展,也可以直接创建SOAP服务端,自动处理请求解析:

class CheckInfoService {
    public function ApplyTransactionRequest($params) {
        // $params会自动包含SOAP请求中的所有参数
        $loginId = $params['Header']['LoginID'];
        $password = $params['Header']['Password'];
        
        // 根据用户信息返回响应
        if ($loginId === 'NGOLoanPay') {
            return ['Result' => '验证通过,返回专属数据'];
        } else {
            return ['Result' => '未知用户'];
        }
    }
}

// 创建SOAP服务端
$server = new SoapServer(null, [
    'uri' => 'http://tempuri.org/',
    'soap_version' => SOAP_1_2 // 对应SOAP 1.2版本,与请求匹配
]);
$server->setClass('CheckInfoService');
$server->handle();

这种方式不需要手动解析XML,SOAP扩展会自动将请求映射为对象或数组,开发效率更高。

内容的提问来源于stack exchange,提问作者user1643268

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 19:04:06