【问题标题】:PHP: Write SOAP request containing XML data and SOAPHeaderPHP:编写包含 XML 数据和 SOAPHeader 的 SOAP 请求
【发布时间】:2014-06-14 14:53:29
【问题描述】:

您好,我遇到了关于 PHP SOAP 请求的问题,我已经用尽了网络上的示例。以下是我需要发送的请求 XML。

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://schemas.navitaire.com/WebServices/ISessionManager/Logon</Action>
<h:ContractVersion xmlns:h="http://schemas.navitaire.com/WebServices">330</h:ContractVersion>
</s:Header>
<s:Body>
<LogonRequest xmlns="http://schemas.navitaire.com/WebServices/ServiceContracts/SessionService">
  <logonRequestData xmlns:d4p1="http://schemas.navitaire.com/WebServices/DataContracts/Session" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <d4p1:DomainCode>WWW</d4p1:DomainCode>
    <d4p1:AgentName>API****</d4p1:AgentName>
    <d4p1:Password>********</d4p1:Password>
    <d4p1:LocationCode i:nil="true" />
    <d4p1:RoleCode>APIB</d4p1:RoleCode>
    <d4p1:TerminalInfo i:nil="true" />
  </logonRequestData>
</LogonRequest>
</s:Body>
</s:Envelope>

WSDL 包含@987654321@

我试过下面的代码

$test = array("DomainCode"=>"WWW","AgentName"=>"API****",
              "Password"=>"******","RoleCode"=>"APIB",
              "LocationCode"=>"","TerminalInfo"=>"");

$wsdl = "https://trtestr3xapi.navitaire.com/sessionmanager.svc?wsdl";

$client = new SoapClient($wsdl, array('trace' => 1,'exceptions' => true));

$header = new SoapHeader('http://schemas.navitaire.com/WebServices/ISessionManager/Logon','ContractVersion','330', '1');
$client->__setSoapHeaders($header);

try {    
$logon_request = $client->Logon($test);
print_r($logon_request);
echo "success!";
} catch (SoapFault $soap_error) {
echo $soap_error;
echo "error!";
}

我已经使用$client-&gt;__getFunctions()生成了函数

 array(4) {
 [0]=>
 string(54) "void ChangePassword(ChangePasswordRequest $parameters)"
 [1]=>
 string(45) "LogonResponse Logon(LogonRequest $parameters)"
 [2]=>
 string(38) "void Logout(LogoutRequest $parameters)"
 [3]=>
 string(75) "TransferSessionResponse TransferSession(TransferSessionRequest $parameters)"
 }

类型在这个链接@987654322@

WSDL 中包含的链接@987654323@ 有ContractVersion 信息

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://schemas.navitaire.com/WebServices" elementFormDefault="qualified" targetNamespace="http://schemas.navitaire.com/WebServices">
<xs:element name="ContractVersion" type="xs:int"/>
<xs:element name="LogonResponse">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="Signature" nillable="true" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Signature" nillable="true" type="xs:string"/>
</xs:schema>

代码更新

$wsdl = 'https://trtestr3xapi.navitaire.com/sessionmanager.svc?wsdl';
$header = new SoapHeader('http://schemas.navitaire.com/WebServices','ContractVersion','330', '1');

$ns_d4p1 = 'http://schemas.navitaire.com/WebServices/DataContracts/Session';
$ns_i = 'http://www.w3.org/2001/XMLSchema-instance';

$client = new SoapClient($wsdl, array('trace' => 1));
$client->__setSoapHeaders($header);

$logonResquestData = new SimpleXMLElement("<logonRequestData xmlns:i='$ns_i' xmlns:d4p1='$ns_d4p1' />");

$logonResquestData->addChild('d4p1:DomainCode', 'WWW', $ns_d4p1);
$logonResquestData->addChild('d4p1:AgentName', 'APISERANGOONAT', $ns_d4p1);
$logonResquestData->addChild('d4p1:Password', 'Newskies-1', $ns_d4p1);
$logonResquestData->addChild('d4p1:LocationCode', null, $ns_d4p1)->addAttribute('i:nil', 'true', $ns_i);
$logonResquestData->addChild('d4p1:RoleCode', 'APIB', $ns_d4p1);
$logonResquestData->addChild('d4p1:TerminalInfo', null, $ns_d4p1)->addAttribute('i:nil', 'true', $ns_i);

//var_dump($logonResquestData->asXML());

$logon_request = $client->Logon($logonResquestData);

return $logon_request;

以上代码抛出如下错误

Fatal error: Uncaught SoapFault exception: [a:InternalServiceFault] LogonRequest.AgentName:LengthStringAttribute: The value of LogonRequest.AgentName:LengthStringAttribute is empty, but is not optional. in C:\Inetpub\vhosts\ezyflying.com\tiger\x.php:22 Stack trace: #0 C:\Inetpub\vhosts\ezyflying.com\tiger\x.php(22): SoapClient->__call('Logon', Array) #1 C:\Inetpub\vhosts\ezyflying.com\tiger\x.php(22): SoapClient->Logon(Object(SimpleXMLElement)) #2 {main} thrown in C:\Inetpub\vhosts\ezyflying.com\tiger\x.php on line 22

【问题讨论】:

  • 我在答案中添加了有关创建作为参数发送到soap 请求的数据的信息。我希望它可以帮助您解决问题。
  • 我回滚了上一个问题。如果您进行激进的编辑以更改问题,您的帐户可能会被标记。如果您有一个新主题,请创建一个新问题来解决它并链接到上一个问题。
  • 谢谢你的提示 :)
  • 既然您解决了标题问题,我实际上建议您创建一个 问题专注 将参数传递给soap 客户端。为了让那些试图回答它的人更容易,您应该在问题中包含 relevant 代码的摘录,即:WSDL、LogonRequestlogonRequestData 的架构定义和每个logonRequestData 子元素。如果没有这些信息,您将很难得到一个好的答案。写一个清晰、客观的问题,标题清晰,涉及一个问题。你的机会会更高。
  • 我一定会试试看的:)

标签: php xml web-services soap wsdl


【解决方案1】:

该错误表示您在声明标头“无法理解”时使用的命名空间中的标头 ContractVersion。这是因为在此目标命名空间的架构中可能没有声明 ContractVersion 元素。

根据您的 SOAP 请求,ContractVersion 属于 另一个 命名空间:

<h:ContractVersion xmlns:h="http://schemas.navitaire.com/WebServices">

添加标题时应该使用 that 命名空间:

$header = new SoapHeader('http://schemas.navitaire.com/WebServices','ContractVersion','330', '1');

至于您的LogonRequest 数据,根据您期望生成的结果,您需要向其中添加一个LogonRequestData 对象。您的架构不可用,我不知道使用 PHP API 的确切语法。一种方法是将有效负载添加为 literal XML。您可能必须为此在 SOAP 客户端中设置一些配置,我不确定这是否是 PHP 的标准推荐过程。如果您可以发送文字 XML,那么您可以构建一个 &lt;logonRequestData&gt; 对象,就像您使用以下代码发布的那样:

$ns_d4p1 = 'http://schemas.navitaire.com/WebServices/DataContracts/Session';
$ns_i = 'http://www.w3.org/2001/XMLSchema-instance';

$logonResquestData = new SimpleXMLElement("<logonRequestData xmlns:i='$ns_i' xmlns:d4p1='$ns_d4p1' />");

$logonResquestData->addChild('d4p1:DomainCode', 'WWW', $ns_d4p1);
$logonResquestData->addChild('d4p1:AgentName', 'API****', $ns_d4p1);
$logonResquestData->addChild('d4p1:Password', '****', $ns_d4p1);
$logonResquestData->addChild('d4p1:LocationCode', null, $ns_d4p1)->addAttribute('i:nil', 'true', $ns_i);
$logonResquestData->addChild('d4p1:RoleCode', 'APIB', $ns_d4p1);
$logonResquestData->addChild('d4p1:TerminalInfo', null, $ns_d4p1)->addAttribute('i:nil', 'true', $ns_i);

您可以通过打印检查上面的代码是否生成了正确的 XML:

print_r($logonResquestData->asXML());

现在您必须将该对象添加到您的LogonRequest 对象中,方法是将其作为参数传递给您的Logon 操作。我不确定确切的语法。您可能需要添加SoapParamSoapVar。您建议使用数组。无论采用何种方法,您都必须在尝试发送之前对其进行测试并查看它是否生成了正确的 XML。这样调试会更容易。

【讨论】:

  • 嗨!很高兴再次见到你stackoverflow.com/questions/24099302/…
  • 哦,原来是同一个问题。还是没修好?如果没有看到您的架构(LogonRequest 元素),很难知道您的请求应该如何形成。
  • 我想让您访问我的服务器,以便您查看。我已经就同一问题提出了很多问题 :( 不幸的是,我无法向其他人寻求帮助。你能通过 teamviewer 帮助我吗?我知道 der 应该是一个简单的解决方法,但不知道 SOAP 或 XML
  • 打开包含LoginRequest 的元素声明的架构。在您之前的问题中,您将它包含在LoginResponse 中,因此应该不难找到。或者,您可以将架构放在这里或粘贴到粘贴箱中。这会很有帮助。
猜你喜欢
  • 2017-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-01
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多