我尝试使用PHP使用SOAP服务时遇到了一个奇怪的问题。它忽略了我的请求,并不断返回上一个命令的结果! SOAP驻留在一台收银机中,它有一个'错误'的wsdl指向一个公共IP端点,我不得不手动编辑它。 WSDL文件是http://192.168.1.20/MyEcrResponce.wsdl我下载了它,并以“192.168.1.20”替换了所有错误的IP引用,然后我在本地保存它作为MyEcrResponce.wsdl:PHP SOAP不断返回旧结果
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://192.168.1.20/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" targetNamespace="http://192.168.1.20/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="http://192.168.1.20/">
<s:element name="Cmd">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="CmdText" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="CmdResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="CmdReply" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="LcdLine1" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="LcdLine2" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="GetAppStatus">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="SerialNo" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="RetData" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="GetAppStatusResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="GetAppStatusResult" type="s:unsignedByte" />
<s:element minOccurs="1" maxOccurs="1" name="RetData" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
</s:schema>
</wsdl:types>
<wsdl:message name="CmdSoapIn">
<wsdl:part name="parameters" element="tns:Cmd" />
</wsdl:message>
<wsdl:message name="CmdSoapOut">
<wsdl:part name="parameters" element="tns:CmdResponse" />
</wsdl:message>
<wsdl:message name="GetAppStatusSoapIn">
<wsdl:part name="parameters" element="tns:GetAppStatus" />
</wsdl:message>
<wsdl:message name="GetAppStatusSoapOut">
<wsdl:part name="parameters" element="tns:GetAppStatusResponse" />
</wsdl:message>
<wsdl:portType name="MyEcrResponceSoap">
<wsdl:operation name="Cmd">
<wsdl:input message="tns:CmdSoapIn" />
<wsdl:output message="tns:CmdSoapOut" />
</wsdl:operation>
<wsdl:operation name="GetAppStatus">
<wsdl:input message="tns:GetAppStatusSoapIn" />
<wsdl:output message="tns:GetAppStatusSoapOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="MyEcrResponceSoap" type="tns:MyEcrResponceSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="Cmd">
<soap:operation soapAction="http://192.168.1.20/Cmd" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="GetAppStatus">
<soap:operation soapAction="http://192.168.1.20/GetAppStatus" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="MyEcrResponce">
<wsdl:port name="MyEcrResponceSoap" binding="tns:MyEcrResponceSoap">
<soap:address location="http://192.168.1.20/MyEcrResponce/" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
我已经使用的形式在C#中的客户端,取而代之的溶液中所有引用的公网IP 192.168.1.20,和正常工作:
private void button1_Click(object sender, EventArgs e)
{
string reply = "";
string LcdMsg1 = "";
string LcdMsg2 = "";
Uri ur = new Uri("http://192.168.1.20/MyEcrResponce.cgx");
DeviceWS.MyEcrResponceSoapClient DevHD = new DeviceWS.MyEcrResponceSoapClient();
DevHD.Endpoint.Address = new System.ServiceModel.EndpointAddress(ur);
DevHD.ClientCredentials.UserName.UserName = "user";
DevHD.ClientCredentials.UserName.Password = "pass";
reply = DevHD.Cmd(CmdTxt.Text, out LcdMsg1, out LcdMsg2);
ReplyTxt.Text = reply;
LCD01.Text = LcdMsg1;
LCD02.Text = LcdMsg2;
}
我的PHP客户端看起来是这样的:
$client = new SoapClient(
dirname(__FILE__) . DIRECTORY_SEPARATOR . 'MyEcrResponce.wsdl',
array('location' => 'http://192.168.1.20/MyEcrResponce.cgx',
'login' => 'user',
'password' => 'pass',
'trace' => 0,
'cache_wsdl' => WSDL_CACHE_NONE));
$cmd = new StdClass();
$cmd->CmdText = 'a/';
var_dump($client->Cmd($cmd));
无论WHI ch组合我尝试在PHP中总是得到C#client命令的最后结果。似乎所有使用PHP的请求都被忽略。似乎有一个C#可以跳过的缓存,但PHP不能。在php.ini中,'soap.wsdl_cache_enabled'和'soap.wsdl_cache'都设置为0.我使用SoapUI和其他SOAP测试人员获得相同(错误)的行为。有任何想法吗?
更新1: PHP $ client - > __ getTypes();返回此:
array (4) [
string (31) "struct Cmd {
string CmdText;
}"
string (76) "struct CmdResponse {
string CmdReply;
string LcdLine1;
string LcdLine2;
}"
string (58) "struct GetAppStatus {
string SerialNo;
string RetData;
}"
string (82) "struct GetAppStatusResponse {
unsignedByte GetAppStatusResult;
string RetData;
}"
]
更新2:使用this post我启用跟踪日志C#客户机来检查工作的SOAP请求,这是这一个:
{
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://192.168.1.20/Cmd"
Accept-Encoding: gzip, deflate,gzip, deflate
Authorization: Basic xxxxxxxxxxxxxxxx
Host: 192.168.1.20
Content-Length: 207
Expect: 100-continue
}
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<Cmd xmlns="http://192.168.1.20/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<CmdText>a/</CmdText>
</Cmd>
</s:Body>
</s:Envelope>
不幸的是,结果还是一样当我将请求复制粘贴到PHP或SoapUI时。
更新3:所以,今天是星期一。收银机和PHP服务器都在星期五关闭,我今天打开它们。我在运行PHP脚本之前清除了PHP服务器中的所有缓存文件,并且收到了我在星期五发送的最后一个成功命令的回复!我点附近相信,我必须非常愚蠢的......
尝试把 的ini_set( 'soap.wsdl_cache_enabled', '0'); ini_set('soap.wsdl_cache_ttl','0'); – WhSol
我已经提到缓存被禁用。 – nasos