我正在尝试使用PHP连接到SOAP API,但不断收到以下错误:
Fatal error: SOAP-ERROR: Encoding: Violation of encoding rules
以下是Web服务的WSDL:
<?xml version="1.0" encoding="ISO-8859-1"?>
<definitions xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://localhost/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://localhost/">
<types>
<xsd:schema targetNamespace="http://localhost/"
>
<xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
<xsd:import namespace="http://schemas.xmlsoap.org/wsdl/" />
<xsd:complexType name="LoyaltySchemeSignUpPacket">
<xsd:all>
<xsd:element name="auth_id" type="xsd:string"/>
<xsd:element name="member_id" type="xsd:string"/>
<xsd:element name="email" type="xsd:string"/>
<xsd:element name="customername" type="xsd:string"/>
<xsd:element name="first_name" type="xsd:string"/>
<xsd:element name="last_name" type="xsd:string"/>
<xsd:element name="gender" type="xsd:string"/>
<xsd:element name="date_of_birth" type="xsd:string"/>
<xsd:element name="address1" type="xsd:string"/>
<xsd:element name="address2" type="xsd:string"/>
<xsd:element name="address3" type="xsd:string"/>
<xsd:element name="address4" type="xsd:string"/>
<xsd:element name="address5" type="xsd:string"/>
<xsd:element name="address6" type="xsd:string"/>
<xsd:element name="postcode" type="xsd:string"/>
<xsd:element name="telephone" type="xsd:string"/>
<xsd:element name="tsa_flag" type="xsd:string"/>
<xsd:element name="nomail" type="xsd:string"/>
<xsd:element name="climbers_flag" type="xsd:string"/>
<xsd:element name="outdoor_flag" type="xsd:string"/>
<xsd:element name="staff_referral_id" type="xsd:string"/>
<xsd:element name="mountainerring" type="xsd:string"/>
<xsd:element name="news" type="xsd:string"/>
<xsd:element name="running" type="xsd:string"/>
<xsd:element name="sale" type="xsd:string"/>
<xsd:element name="skiing" type="xsd:string"/>
<xsd:element name="snowboarding" type="xsd:string"/>
<xsd:element name="travelling" type="xsd:string"/>
<xsd:element name="trekking" type="xsd:string"/>
<xsd:element name="cycling" type="xsd:string"/>
<xsd:element name="camping" type="xsd:string"/>
<xsd:element name="groupid" type="xsd:string"/>
</xsd:all>
</xsd:complexType>
<xsd:complexType name="LoyaltySchemeSignUpResponsePacket">
<xsd:all>
<xsd:element name="status" type="xsd:int"/>
<xsd:element name="customer_id" type="xsd:string"/>
</xsd:all>
</xsd:complexType>
<xsd:complexType name="LoyaltySchemeVouchPacket">
<xsd:all>
<xsd:element name="auth_id" type="xsd:string"/>
<xsd:element name="disctype" type="xsd:string"/>
<xsd:element name="amount" type="xsd:string"/>
<xsd:element name="qnty" type="xsd:string"/>
<xsd:element name="expiry" type="xsd:string"/>
<xsd:element name="includeid" type="xsd:string"/>
<xsd:element name="excludeid" type="xsd:string"/>
<xsd:element name="minspend" type="xsd:decimal"/>
<xsd:element name="description" type="xsd:string"/>
<xsd:element name="maxdiscount" type="xsd:string"/>
<xsd:element name="frequency" type="xsd:string"/>
<xsd:element name="freq_qnty" type="xsd:string"/>
<xsd:element name="vouchercap" type="xsd:string"/>
<xsd:element name="groupid" type="xsd:string"/>
</xsd:all>
</xsd:complexType>
<xsd:complexType name="LoyaltySchemeVouchResponsePacket">
<xsd:all>
<xsd:element name="Type_ID" type="xsd:int"/>
<xsd:element name="Status" type="xsd:int"/>
</xsd:all>
</xsd:complexType>
<xsd:complexType name="LoyaltySchemeVouchCodePacket">
<xsd:all>
<xsd:element name="auth_id" type="xsd:string"/>
<xsd:element name="type_id" type="xsd:string"/>
<xsd:element name="customerid" type="xsd:string"/>
</xsd:all>
</xsd:complexType>
<xsd:complexType name="LoyaltySchemeVouchCodeResponsePacket">
<xsd:all>
<xsd:element name="Code_ID" type="xsd:string"/>
<xsd:element name="Status" type="xsd:int"/>
</xsd:all>
</xsd:complexType>
<xsd:complexType name="LoyaltySchemeVoucherCheckPacket">
<xsd:all>
<xsd:element name="auth_id" type="xsd:string"/>
<xsd:element name="email_url" type="xsd:string"/>
<xsd:element name="customer_id" type="xsd:string"/>
<xsd:element name="voucher_code" type="xsd:string"/>
</xsd:all>
</xsd:complexType>
<xsd:complexType name="LoyaltySchemeVoucherCheckResponse">
<xsd:all>
<xsd:element name="status" type="xsd:int"/>
<xsd:element name="statustext" type="xsd:string"/>
<xsd:element name="emailurl" type="xsd:string"/>
<xsd:element name="customer_id" type="xsd:int"/>
<xsd:element name="vouch_expires" type="xsd:string"/>
<xsd:element name="disc_claimed" type="xsd:string"/>
<xsd:element name="number_uses" type="xsd:string"/>
<xsd:element name="transaction_cap" type="xsd:string"/>
<xsd:element name="voucher_cap" type="xsd:string"/>
<xsd:element name="voucherdetails" type="tns:LoyaltySchemeVouchPacket"/>
</xsd:all>
</xsd:complexType>
<xsd:complexType name="LoyaltySchemeVoucherRedeemPacket">
<xsd:all>
<xsd:element name="auth_id" type="xsd:string"/>
<xsd:element name="customer_id" type="xsd:string"/>
<xsd:element name="customer_email" type="xsd:string"/>
<xsd:element name="amount_disc" type="xsd:string"/>
<xsd:element name="voucher_code" type="xsd:string"/>
<xsd:element name="order_number" type="xsd:string"/>
</xsd:all>
</xsd:complexType>
<xsd:complexType name="LoyaltySchemeVoucherRedeemResponse">
<xsd:all>
<xsd:element name="status" type="xsd:int"/>
<xsd:element name="statustext" type="xsd:string"/>
</xsd:all>
</xsd:complexType>
<xsd:complexType name="LoyaltySchemecustomerpacket">
<xsd:all>
<xsd:element name="auth_id" type="xsd:string"/>
<xsd:element name="customerid" type="xsd:string"/>
<xsd:element name="customer_email" type="xsd:string"/>
</xsd:all>
</xsd:complexType>
<xsd:complexType name="LoyaltySchemecustomerresponsepacket">
<xsd:all>
<xsd:element name="status" type="xsd:int"/>
<xsd:element name="statustext" type="xsd:int"/>
<xsd:element name="member_id" type="xsd:string"/>
<xsd:element name="email" type="xsd:string"/>
<xsd:element name="customername" type="xsd:string"/>
<xsd:element name="firstname" type="xsd:string"/>
<xsd:element name="surname" type="xsd:string"/>
<xsd:element name="gender" type="xsd:string"/>
<xsd:element name="date_of_birth" type="xsd:string"/>
<xsd:element name="address1" type="xsd:string"/>
<xsd:element name="address2" type="xsd:string"/>
<xsd:element name="address3" type="xsd:string"/>
<xsd:element name="address4" type="xsd:string"/>
<xsd:element name="address5" type="xsd:string"/>
<xsd:element name="address6" type="xsd:string"/>
<xsd:element name="postcode" type="xsd:string"/>
<xsd:element name="phone" type="xsd:string"/>
<xsd:element name="member" type="xsd:string"/>
<xsd:element name="tsa_flag" type="xsd:string"/>
<xsd:element name="nomail" type="xsd:string"/>
<xsd:element name="climbers_flag" type="xsd:string"/>
<xsd:element name="outdoor_flag" type="xsd:string"/>
<xsd:element name="staff_referral_id" type="xsd:string"/>
<xsd:element name="mountainerring" type="xsd:string"/>
<xsd:element name="news" type="xsd:string"/>
<xsd:element name="running" type="xsd:string"/>
<xsd:element name="sale" type="xsd:string"/>
<xsd:element name="skiing" type="xsd:string"/>
<xsd:element name="snowboarding" type="xsd:string"/>
<xsd:element name="travelling" type="xsd:string"/>
<xsd:element name="trekking" type="xsd:string"/>
<xsd:element name="cycling" type="xsd:string"/>
<xsd:element name="camping" type="xsd:string"/>
<xsd:element name="groupid" type="xsd:string"/>
</xsd:all>
</xsd:complexType>
</xsd:schema>
</types>
<message name="ws_loyalty_signupRequest">
<part name="signuprec" type="tns:LoyaltySchemeSignUpPacket" /></message>
<message name="ws_loyalty_signupResponse">
<part name="response" type="tns:LoyaltySchemeSignUpResponsePacket" /></message>
<message name="ws_loyalty_updateRequest">
<part name="signuprec" type="tns:LoyaltySchemeSignUpPacket" /></message>
<message name="ws_loyalty_updateResponse">
<part name="response" type="tns:LoyaltySchemeSignUpResponsePacket" /></message>
<message name="ws_voucher_typesRequest">
<part name="vouchercre" type="tns:LoyaltySchemeVouchPacket" /></message>
<message name="ws_voucher_typesResponse">
<part name="response" type="tns:LoyaltySchemeVouchResponsePacket" /></message>
<message name="ws_voucher_codesRequest">
<part name="vouchercode" type="tns:LoyaltySchemeVouchCodePacket" /></message>
<message name="ws_voucher_codesResponse">
<part name="response" type="tns:LoyaltySchemeVouchCodeResponsePacket" /></message>
<message name="ws_voucher_checkRequest">
<part name="customervoucher" type="tns:LoyaltySchemeVoucherCheckPacket" /></message>
<message name="ws_voucher_checkResponse">
<part name="response" type="tns:LoyaltySchemeVoucherCheckResponse" /></message>
<message name="ws_voucher_redeemRequest">
<part name="customervoucher" type="tns:LoyaltySchemeVoucherRedeemPacket" /></message>
<message name="ws_voucher_redeemResponse">
<part name="response" type="tns:LoyaltySchemeVoucherRedeemResponse" /></message>
<message name="ws_customer_infoRequest">
<part name="customerpacket" type="tns:LoyaltySchemecustomerpacket" /></message>
<message name="ws_customer_infoResponse">
<part name="response" type="tns:LoyaltySchemecustomerresponsepacket" /></message>
<portType name="LoyaltySchemePortType">
<operation name="ws_loyalty_signup">
<documentation>Pass signup details from customer and return existing ID if found or create new customer record and return new ID</documentation>
<input message="tns:ws_loyalty_signupRequest"/>
<output message="tns:ws_loyalty_signupResponse"/>
</operation>
<operation name="ws_loyalty_update">
<documentation>Pass update details from customer and return update status and Member ID</documentation>
<input message="tns:ws_loyalty_updateRequest"/>
<output message="tns:ws_loyalty_updateResponse"/>
</operation>
<operation name="ws_voucher_types">
<documentation>Generation of the Voucher Types</documentation>
<input message="tns:ws_voucher_typesRequest"/>
<output message="tns:ws_voucher_typesResponse"/>
</operation>
<operation name="ws_voucher_codes">
<documentation>Generation of the Voucher Types</documentation>
<input message="tns:ws_voucher_codesRequest"/>
<output message="tns:ws_voucher_codesResponse"/>
</operation>
<operation name="ws_voucher_check">
<documentation>Validate voucher code</documentation>
<input message="tns:ws_voucher_checkRequest"/>
<output message="tns:ws_voucher_checkResponse"/>
</operation>
<operation name="ws_voucher_redeem">
<documentation>Redeem voucher by code</documentation>
<input message="tns:ws_voucher_redeemRequest"/>
<output message="tns:ws_voucher_redeemResponse"/>
</operation>
<operation name="ws_customer_info">
<documentation>Get customer information </documentation>
<input message="tns:ws_customer_infoRequest"/>
<output message="tns:ws_customer_infoResponse"/>
</operation>
</portType>
<binding name="LoyaltySchemeBinding" type="tns:LoyaltySchemePortType">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="ws_loyalty_signup">
<soap:operation soapAction="http://localhost/#ws_loyalty_signup" style="rpc"/>
<input><soap:body use="encoded" namespace="http://localhost/" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></input>
<output><soap:body use="encoded" namespace="http://localhost/" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></output>
</operation>
<operation name="ws_loyalty_update">
<soap:operation soapAction="http://localhost/#ws_loyalty_update" style="rpc"/>
<input><soap:body use="encoded" namespace="http://localhost/" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></input>
<output><soap:body use="encoded" namespace="http://localhost/" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></output>
</operation>
<operation name="ws_voucher_types">
<soap:operation soapAction="http://localhost/#ws_voucher_types" style="rpc"/>
<input><soap:body use="encoded" namespace="http://localhost/" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></input>
<output><soap:body use="encoded" namespace="http://localhost/" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></output>
</operation>
<operation name="ws_voucher_codes">
<soap:operation soapAction="http://localhost/#ws_voucher_codes" style="rpc"/>
<input><soap:body use="encoded" namespace="http://localhost/" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></input>
<output><soap:body use="encoded" namespace="http://localhost/" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></output>
</operation>
<operation name="ws_voucher_check">
<soap:operation soapAction="http://localhost/#ws_voucher_check" style="rpc"/>
<input><soap:body use="encoded" namespace="http://localhost/" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></input>
<output><soap:body use="encoded" namespace="http://localhost/" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></output>
</operation>
<operation name="ws_voucher_redeem">
<soap:operation soapAction="http://localhost/#ws_voucher_redeem" style="rpc"/>
<input><soap:body use="encoded" namespace="http://localhost/" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></input>
<output><soap:body use="encoded" namespace="http://localhost/" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></output>
</operation>
<operation name="ws_customer_info">
<soap:operation soapAction="http://localhost/#ws_customer_info" style="rpc"/>
<input><soap:body use="encoded" namespace="http://localhost/" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></input>
<output><soap:body use="encoded" namespace="http://localhost/" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></output>
</operation>
</binding>
<service name="LoyaltyScheme">
<port name="LoyaltySchemePort" binding="tns:LoyaltySchemeBinding">
<soap:address location="http://www.ellisbrigham-uk.com/loyaltyserver.php"/>
</port>
</service>
</definitions>
我使用SOAP UI来测试服务,它在SOAP UI中运行良好。以下是SOAP UI发送的请求:
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:loc="http://localhost/">
<soapenv:Header/>
<soapenv:Body>
<loc:ws_customer_info soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<customerpacket xsi:type="loc:LoyaltySchemecustomerpacket">
<auth_id xsi:type="xsd:string">auth-code-here</auth_id>
<customerid xsi:type="xsd:string">0</customerid>
<customer_email xsi:type="xsd:string">someone@gmail.com</customer_email>
</customerpacket>
</loc:ws_customer_info>
</soapenv:Body>
</soapenv:Envelope>
以下是我使用的导致错误的代码:
<?php
$context = stream_context_create([
'http'=> [
'user_agent' => 'PHPSoapClient'
]
]);
$accent = new \SoapClient( 'http://domain.com/loyaltyserver.php?wsdl', [
'stream_context' => $context,
'cache_wsdl' => WSDL_CACHE_NONE,
'trace' => true
]);
$data = [
'auth_id' => (string) 'my-auth-code',
'customer_email' => (string) 'someone@gmail.com',
'customerid' => (string) 0
];
$result = $accent->ws_customer_info($data);
我使用了__getLastRequest()
,这是它发送的请求:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://localhost/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:ws_customer_info>
<customerpacket xsi:type="ns1:LoyaltySchemecustomerpacket">
<auth_id xsi:type="xsd:string">my-auth-code</auth_id>
<customerid xsi:type="xsd:string">0</customerid>
<customer_email xsi:type="xsd:string">someone@gmail.com</customer_email>
</customerpacket>
</ns1:ws_customer_info>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
正如您所看到的那样,通过比较这两个请求它们是不同的但我不太了解SOAP以了解它们为何不同或导致错误的原因。
更新
如果我捕获异常并使用__getLastResponse()
输出最后一个响应,我可以看到返回的似乎是有效响应。以下是回复:
<?xml version="1.0" encoding="ISO-8859-1"?>
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://localhost/">
<SOAP-ENV:Body>
<ns1:ws_customer_infoResponse xmlns:ns1="http://localhost/">
<response xsi:type="tns:LoyaltySchemecustomerresponsepacket">
<status xsi:type="xsd:int">0</status>
<statustext xsi:type="xsd:int">OK</statustext>
<member_id xsi:nil="true" xsi:type="xsd:string"/>
<email xsi:nil="true" xsi:type="xsd:string"/>
<customername xsi:nil="true" xsi:type="xsd:string"/>
<firstname xsi:nil="true" xsi:type="xsd:string"/>
<surname xsi:nil="true" xsi:type="xsd:string"/>
<gender xsi:nil="true" xsi:type="xsd:string"/>
<date_of_birth xsi:nil="true" xsi:type="xsd:string"/>
<address1 xsi:nil="true" xsi:type="xsd:string"/>
<address2 xsi:nil="true" xsi:type="xsd:string"/>
<address3 xsi:nil="true" xsi:type="xsd:string"/>
<address4 xsi:nil="true" xsi:type="xsd:string"/>
<address5 xsi:nil="true" xsi:type="xsd:string"/>
<address6 xsi:nil="true" xsi:type="xsd:string"/>
<postcode xsi:nil="true" xsi:type="xsd:string"/>
<phone xsi:nil="true" xsi:type="xsd:string"/>
<member xsi:nil="true" xsi:type="xsd:string"/>
<tsa_flag xsi:nil="true" xsi:type="xsd:string"/>
<nomail xsi:nil="true" xsi:type="xsd:string"/>
<climbers_flag xsi:nil="true" xsi:type="xsd:string"/>
<outdoor_flag xsi:nil="true" xsi:type="xsd:string"/>
<staff_referral_id xsi:nil="true" xsi:type="xsd:string"/>
<mountainerring xsi:nil="true" xsi:type="xsd:string"/>
<news xsi:nil="true" xsi:type="xsd:string"/>
<running xsi:nil="true" xsi:type="xsd:string"/>
<sale xsi:nil="true" xsi:type="xsd:string"/>
<skiing xsi:nil="true" xsi:type="xsd:string"/>
<snowboarding xsi:nil="true" xsi:type="xsd:string"/>
<travelling xsi:nil="true" xsi:type="xsd:string"/>
<trekking xsi:nil="true" xsi:type="xsd:string"/>
<cycling xsi:nil="true" xsi:type="xsd:string"/>
<camping xsi:nil="true" xsi:type="xsd:string"/>
<groupid xsi:nil="true" xsi:type="xsd:string"/>
</response>
</ns1:ws_customer_infoResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
答案 0 :(得分:1)
问题出在服务器响应中。
XSD表示<statustext>
标记类型为int
,但是服务器返回字符串OK
,从而中断了响应解析。