PHP构建指定SOAP信封SOAPVAR负载遇「无凭据」错误求助
问题:SOAP请求嵌套凭据结构错误导致「No Credentials Found」
尝试为指定SOAP信封构建PHP对象,因不熟悉PHP语法,在嵌套凭据部分出现问题,端点返回错误提示「No Credentials Found」。
负载示例
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:hyp="http://www.globalprocessing.ae/HyperionWeb"> <soapenv:Header> <hyp:AuthSoapHeader> <hyp:strUserName></hyp:strUserName> <hyp:strPassword></hyp:strPassword> </hyp:AuthSoapHeader> </soapenv:Header> <soapenv:Body> <hyp:Ws_AddUpDelCredentials> <hyp:WSID></hyp:WSID> <hyp:IssCode></hyp:IssCode> <hyp:PublicToken></hyp:PublicToken> <hyp:Action></hyp:Action> <hyp:Credentials> <hyp:Credential> <hyp:ID></hyp:ID> <hyp:Type></hyp:Type> <hyp:Value></hyp:Value> <hyp:KBA_Answer></hyp:KBA_Answer> <hyp:KBA_AnswerOldValue></hyp:KBA_AnswerOldValue> </hyp:Credential> </hyp:Credentials> </hyp:Ws_AddUpDelCredentials> </soapenv:Body></soapenv:Envelope>
现有类结构
class Ws_AddUpDelCredentialsRequest { public $paramData; public function __construct($ns, $instCode, $cardToken, $action, $credentials) { $this->paramData[] = new SoapVar(date('jnmhis') . rand(1000, 9999), null, null, null, 'WSID', $ns); $this->paramData[] = new SoapVar(substr($instCode, 0, 3), null, null, null, 'IssCode', $ns); $this->paramData[] = new SoapVar($cardToken, null, null, null, 'PublicToken', $ns); $this->paramData[] = new SoapVar($action, null, null, null, 'Action', $ns); $this->paramData[] = new SoapVar($credentials, null, null, null, 'Credentials', $ns); } } class Ws_Credential { public $paramData; public function __construct($ns, $id, $type, $value) { $this->paramData[] = new SoapVar($id, null, null, null, 'ID', $ns); $this->paramData[] = new SoapVar($type, null, null, null, 'Type', $ns); $this->paramData[] = new SoapVar($value, null, null, null, 'Value', $ns); } }
调用代码
$addUpDelCredentialsResponse = $soapClient->__soapCall( 'Ws_AddUpDelCredentials', $addUpDelCredentialsRequest->paramData, array("soapaction" => 'http://www.globalprocessing.ae/HyperionWeb' . "/Ws_AddUpDelCredentials"));
解决方案
1. 完善Ws_Credential类,补充缺失字段
原类未包含SOAP负载中的KBA_Answer和KBA_AnswerOldValue字段,需补充:
class Ws_Credential { public $paramData; public function __construct($ns, $id, $type, $value, $kbaAnswer = null, $kbaAnswerOldValue = null) { $this->paramData[] = new SoapVar($id, null, null, null, 'ID', $ns); $this->paramData[] = new SoapVar($type, null, null, null, 'Type', $ns); $this->paramData[] = new SoapVar($value, null, null, null, 'Value', $ns); if ($kbaAnswer !== null) { $this->paramData[] = new SoapVar($kbaAnswer, null, null, null, 'KBA_Answer', $ns); } if ($kbaAnswerOldValue !== null) { $this->paramData[] = new SoapVar($kbaAnswerOldValue, null, null, null, 'KBA_AnswerOldValue', $ns); } } }
2. 创建Ws_Credentials类作为容器
SOAP结构中Credentials是包含Credential的父节点,需单独创建类做层级包装:
class Ws_Credentials { public $paramData; public function __construct($ns, $credential) { // 将单个Credential对象包装到Credentials节点下 $this->paramData[] = new SoapVar($credential->paramData, SOAP_ENC_OBJECT, null, null, 'Credential', $ns); } }
3. 调整Ws_AddUpDelCredentialsRequest构造逻辑
确保Credentials节点正确嵌套到请求结构中:
class Ws_AddUpDelCredentialsRequest { public $paramData; public function __construct($ns, $instCode, $cardToken, $action, $credentials) { $this->paramData[] = new SoapVar(date('jnmhis') . rand(1000, 9999), null, null, null, 'WSID', $ns); $this->paramData[] = new SoapVar(substr($instCode, 0, 3), null, null, null, 'IssCode', $ns); $this->paramData[] = new SoapVar($cardToken, null, null, null, 'PublicToken', $ns); $this->paramData[] = new SoapVar($action, null, null, null, 'Action', $ns); // 传入包装后的Credentials容器对象 $this->paramData[] = new SoapVar($credentials->paramData, SOAP_ENC_OBJECT, null, null, 'Credentials', $ns); } }
4. 修正__soapCall调用方式
__soapCall的第二个参数需为包含请求对象的数组,而非直接传递paramData:
// 构建单个Credential对象 $credential = new Ws_Credential($ns, $id, $type, $value, $kbaAnswer, $kbaAnswerOldValue); // 构建Credentials容器 $credentials = new Ws_Credentials($ns, $credential); // 构建完整请求对象 $addUpDelCredentialsRequest = new Ws_AddUpDelCredentialsRequest($ns, $instCode, $cardToken, $action, $credentials); // 修正后的SOAP调用 $addUpDelCredentialsResponse = $soapClient->__soapCall( 'Ws_AddUpDelCredentials', array($addUpDelCredentialsRequest->paramData), array("soapaction" => 'http://www.globalprocessing.ae/HyperionWeb/Ws_AddUpDelCredentials') );
5. 补充SOAP Header验证
不要遗漏设置SOAP Header中的AuthSoapHeader,否则可能导致请求权限验证失败:
// 创建认证头对象 $authHeader = new SoapVar( array( 'strUserName' => '你的用户名', 'strPassword' => '你的密码' ), SOAP_ENC_OBJECT, null, null, 'AuthSoapHeader', $ns ); // 为SOAP客户端设置认证头 $soapClient->__setSoapHeaders(array($authHeader));
内容的提问来源于stack exchange,提问作者Dannywooly
相关产品推荐
相关产品推荐

