Summary
在这里,我将列出我解决此问题所采取的所有步骤,以供其他人参考。
1.
PHP 很愚蠢地“监听”函数的输入消息来定义它应该使用哪个函数。因此,为每个函数提供不同的输入消息,即使它使用相同的类型或元素。您可能认为这对您来说是一项艰巨的工作,但可以这样做:
<xsi:complexType name="UserCredentials">
<xsi:attribute name="customerID" type="xsi:int"/>
</xsi:complexType>
<xsi:element name="UserCredentials" type="types:UserCredentials"/>
<xsi:element name="UserCredentials1" type="types:UserCredentials"/>
<wsdl:message name="getCustomerCredentials">
<wsdl:part name="body" element="types:UserCredentials"/>
</wsdl:message>
<wsdl:message name="getCustomerCredentials1">
<wsdl:part name="body" element="types:UserCredentials1"/>
</wsdl:message>
接下来,Visual Studio 开始抱怨,我花了几天时间才弄清楚这个愚蠢的简单事情,只需告诉程序您刚刚设置了对象属性:
UserCredentials.customerID = User.CustomerID;
UserCredentials.customerIDSpecified = true;
就是这样。我自己都不敢相信。我花了1.5周,解决方案是两个步骤,请给下面回答的这个人一些票。
Update
我的输入对象没有开始解析为 XML。
//Fix:
您必须告诉程序该属性的设置如下:
UserCredentials.customerID = User.CustomerID;
UserCredentials.customerIDSpecified = true;
Fiddler 显示了这一点:
Input
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<UserCredentials2 xmlns="http://5.157.80.21/servicehandler/wsdl_service.wsdl"/>
</s:Body>
</s:Envelope>
Output
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="types">
<SOAP-ENV:Body>
<ns1:PersoonArray/>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
这段代码有问题吗?
public static List<Klant> GetAllPersonen()
{
List<Klant> list = new List<Klant>();
WeGotchaService.Persoon[] servicePersonen = dpc.getAllPersoonData(UserCredentials);
foreach (WeGotchaService.Persoon p in servicePersonen)
{
Klant k = new Klant(p);
list.Add(k);
}
return list;
}
更新到下面的评论
<xsi:complexType name="UserCredentials">
<xsi:attribute name="customerID" type="xsi:int"/>
</xsi:complexType>
<xsi:element name="UserCredentials" type="tns:UserCredentials" />
<xsi:element name="UserCredentials2" type="tns:UserCredentials"/>
<wsdl:message name="getCustomerCredentials">
<wsdl:part name="body" element="ns:UserCredentials"/>
</wsdl:message>
<wsdl:message name="getCustomerCredentials2">
<wsdl:part name="body" element="ns:UserCredentials2"/>
</wsdl:message>
<wsdl:operation name="getAllLessenData">
<wsdl:input message="ns:getCustomerCredentials"/>
<wsdl:output message="ns2:LessenList"/>
</wsdl:operation>
<wsdl:operation name="getAllPersoonData">
<wsdl:input message="ns:getCustomerCredentials2"/>
<wsdl:output message="ns3:PersoonList"/>
</wsdl:operation>
这似乎有效,除了它现在在 VS10 中返回一个 count=0 数组
另一个更新
评论里有人发了一条link https://bugs.php.net/bug.php?id=49169PHP 的错误报告。倒数第二个评论者声称,他通过将所有消息定义放在其他文件中并将它们包含在这个主要 WSDL 文档中来解决了我遇到的同样问题。我尝试了这个,但没有用,没有任何改变。
UPDATE:
因此,我更改了绑定方法中定义的函数的顺序,并得出以下结论:只有绑定区域中定义的第一个函数有效,因此在这种情况下只有我的 getAllLessenData 有效,因为我将它放在所有其他函数之上。有人看到错误吗?
<wsdl:binding name="DataBinding" type="tns:DataPort">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getAllLessenData">
<soap:operation soapAction="" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getAllPersoonData">
<soap:operation soapAction="" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getAllBetalingData">
<soap:operation soapAction="" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getPersoonLessenData">
<soap:operation soapAction="" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getPersoonBetalingenData">
<soap:operation soapAction="" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
更新结束
我在 WSLD 方面遇到了一点问题(再次)
我的 getAllLessenData (和其他函数)全部返回 NULL,而一个函数 (getAllPersoonData) 返回预期的结果。
WSDL 数组定义:
<xsi:element name="PersoonArray">
<xsi:complexType>
<xsi:sequence>
<xsi:element name="Persoon" type="tns:Persoon" maxOccurs="unbounded"/>
</xsi:sequence>
</xsi:complexType>
</xsi:element>
<xsi:element name="LessenArray">
<xsi:complexType>
<xsi:sequence>
<xsi:element name="Les" type="tns:Les" maxOccurs="unbounded"/>
</xsi:sequence>
</xsi:complexType>
</xsi:element>
WSDL 复杂类型定义:
<xsi:complexType name="Les">
<xsi:attribute name="ID" type="xsi:int"/>
// lots of stuff //
<xsi:attribute name="Definitief" type="xsi:boolean"/>
</xsi:complexType>
<xsi:complexType name="Persoon">
<xsi:attribute name="ID" type="xsi:int"/>
<// lots of stuff //
<xsi:attribute name="Laatste_keer_bewerkt" type="xsi:dateTime"/>
</xsi:complexType>
WSDL 消息定义:
<wsdl:message name="getCustomerID">
<wsdl:part name="CustomerID" type="xs:int"/>
</wsdl:message>
<wsdl:message name="PersoonList">
<wsdl:part name="PersoonList" element="tns:PersoonArray"/>
</wsdl:message>
<wsdl:message name="LessenList">
<wsdl:part name="LessenList" element="tns:LessenArray"/>
</wsdl:message>
WSDL 端口类型定义
<wsdl:operation name="getAllPersoonData">
<wsdl:input message="tns:getCustomerID"/>
<wsdl:output message="tns:PersoonList"/>
</wsdl:operation>
<wsdl:operation name="getAllLessenData">
<wsdl:input message="tns:getCustomerID"/>
<wsdl:output message="tns:LessenList"/>
</wsdl:operation>
WSDL 绑定定义
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getAllPersoonData">
<soap:operation soapAction="http://localhost/weGotcha/servicehandler/servicehandler.php" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getAllLessenData">
<soap:operation soapAction="http://localhost/weGotcha/servicehandler/servicehandler.php" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
PHP函数定义:
function getAllPersoonData($customer_ID)
{
connectToDB();
//////////// yes I use mysqli now /////////////
$sql = "SELECT * FROM personen WHERE Customer_ID='". $customer_ID ."'";
$sql = mysql_query($sql) or die(mysql_error());
$result = array();
while($row = mysql_fetch_array($sql))
{
$row["Kosten_totaal"] = mysql_fetch_array(mysql_query("SELECT SUM(Kosten) FROM lessen WHERE Persoon_ID='". $row["ID"] ."'"))[0];
$row["Totaal_betaald"] = mysql_fetch_array(mysql_query("SELECT SUM(Bedrag) FROM betalingen WHERE Persoon_ID='". $row["ID"] ."'"))[0];
$lkbDatum = strtotime($row["Laatste_keer_bewerkt"]);
$row["Laatste_keer_bewerkt"] = date("Y-m-d", $lkbDatum) . "T". date("H:i:s", $lkbDatum);
$result[] = $row;
}
mysql_close();
return $result;
}
function getAllLessenData($customer_ID)
{
$sql = "SELECT * FROM lessen WHERE Customer_ID='". $customer_ID ."'";
//////////// yes I use mysqli now /////////////
connectToDB();
$sql = mysql_query($sql) or die(mysql_error());
$result = array();
while($row = mysql_fetch_array($sql))
{
$result[] = $row;
}
mysql_close();
return $result;
}
$server = new SoapServer("wsdl_service.wsdl");
$server->AddFunction("getAllPersoonData");
$server->AddFunction("getAllBetalingData");
$server->AddFunction("getPersoonBetalingData");
$server->AddFunction("getAllLessenData");
$server->AddFunction("getPersoonLessenData");
$server->handle();
Test.php
$client = new SoapClient("http://localhost/weGotcha/servicehandler/wsdl_service.wsdl", array("trace" => 1));
var_dump($client->__getFunctions());
var_dump($client->getAllLessenData(1));
var_dump($client->__getLastRequest());
var_dump($client->__getLastResponse());
返回:
array (size=5)
0 => string 'PersoonArray getAllPersoonData(int $CustomerID)' (length=47)
1 => string 'LessenArray getAllLessenData(int $CustomerID)' (length=45)
2 => string 'BetalingenArray getAllBetalingData(int $CustomerID)' (length=51)
3 => string 'LessenArray getPersoonLessenData(int $getCustomerID, int $getPersoonID)' (length=71)
4 => string 'BetalingenArray getPersoonBetalingenData(int $getCustomerID, int $getPersoonID)' (length=79)
null
string '<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><CustomerID>1</CustomerID></SOAP-ENV:Body></SOAP-ENV:Envelope>
' (length=195)
string '<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://localhost/weGotcha/servicehandler/wsdl_service.wsdl"><SOAP-ENV:Body> <ns1:PersoonArray><ns1:Persoon ID="1" Voornaam="xxxx" Achternaam="xxxx" Adres="xxxx" Postcode="xxxx" Woonplaats="xxxx" Email_adres="xxxx" Telefoonnummer="xxxx" Geboortedatum="0001-01-01" CBR_kandidaatnummer="12381233" Rijbewijs="2" Theorie_behaald="false" Theorie_po'... (length=3096)
我的数据库中有一些行,直接从 servicehandler.php 调用 getAllLessenData(1) 会返回预期结果。但是,在我的 test.php 中,它仅返回 NULL,而 getLastResponse 返回 getAllPersoonData(1) 的结果。
这两个函数定义对我来说看起来是一样的,哎呀,我复制粘贴了其中的大部分内容。我尝试更改名称空间等。谷歌。但它不起作用。有任何想法吗?
如果您需要更多信息,请回复。