WSDL PHP 函数返回 null 而其他函数返回预期结果 [英] WSDL PHP function returns null while other function returns expected result

查看:44
本文介绍了WSDL PHP 函数返回 null 而其他函数返回预期结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

总结

在这里,我将列出我为解决此问题而采取的所有步骤,以供其他人参考.

Here I'll list all steps I've taken to solve this problem as reference for others.

1.PHP,足够愚蠢,听"一个函数的输入消息来定义它应该使用什么函数.所以给你的每一个函数一个不同的输入消息,即使它使用相同的类型或元素.您可能认为这是您需要解决的相当多的工作,但可以这样做:

1. PHP, stupidly enough, 'listens' to the input message of a function to define what function it should use. So give every one of your functions a different input message, even though it uses the same type or element. You may think this is quite some work for you to solve but it can be done like this:

<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 发牢骚,我花了几天的时间想出这个愚蠢的简单事情,告诉程序您刚刚设置了对象属性:

Next, Visual Studio was whining, I spend a couple of days figuring this stupidly idiotic simple thing out, just tell the program you have just set the objects property:

 UserCredentials.customerID = User.CustomerID;
 UserCredentials.customerIDSpecified = true;

就是这样.我自己都不敢相信.我花了 1,5 周,解决方案是两个步骤,请给下面回答的这个人一些投票.

And that's it. I can't believe it myself. I spend 1,5 weeks, solution is two steps, please give this guy who answered below some votes up.

更新

我的输入对象没有开始解析为 XML.

My input object is NOT begin parsed into XML.

//修正:

你必须告诉程序这个属性是这样设置的:

You have to tell the program that the property is set like so:

UserCredentials.customerID = User.CustomerID;
UserCredentials.customerIDSpecified = true;

Fiddler 显示:

Fiddler shows this:

输入

<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>

输出

<?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:E‌​nvelope>

这段代码有问题吗?

    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 数组

This seems to work, except that it now returns a count=0 array in VS10

另一个更新

在评论中,有人发布了一个 link 到一个 PHP 错误报告.倒数第二位评论者声称他通过将所有消息定义放在其他文件中并将它们包含在此主要 WSDL 文档中来解决我遇到的相同问题.我试过了,但没有用,没有任何改变.

In the comments someone posted a link to a bug report with PHP. The second last commenter claimed that he worked around this same issue I have by placing all the message defenitions in other files and included them in this main WSDL document. I tried this but it did not work, nothing changed.

更新:

所以我改变了绑定方法中定义的函数的顺序,并得出以下结论:只有绑定区域中定义的第一个函数有效,所以在这种情况下只有我的getAllLessenData有效,因为我把它放在所有其他.有人看到错误吗?

So I changed the order of the functions defined in the binding method, and figured out the following: only the first function defined in the binding area works, so in this case only my getAllLessenData works, because I put it above all the others. Does anyone see an error?

 <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 有一点问题(再次)

I'm having a little problem with WSLD (again)

我的 getAllLessenData(和其他函数)都返回 NULL,而一个函数 (getAllPersoonData) 返回预期值.

my getAllLessenData (and other functions) all return NULL while one function (getAllPersoonData) returns what is expected.

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 complexType 定义:

WSDL complexType defenitions:

        <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 portType defenition

 <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();

测试.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) 的结果.

There are rows in my database and calling getAllLessenData(1) directly from my servicehandler.php returns the expected results. however, in my test.php it simply returns NULL and the getLastResponse returns the results from getAllPersoonData(1).

两个函数定义对我来说看起来一样,见鬼,我复制粘贴了大部分.我尝试更改名称空间等.谷歌.但它没有用.有什么想法吗?

Both function defenitions look the same for me, heck I copy-pasted most of it. I tried changing namespaces etc. google. but it didn't work. Any ideas?

如果您需要更多信息,请回复.

If you need more info please respond.

推荐答案

EDIT 1: 这可能也与 getAllPersoonDatagetAllLessenData 具有相同的事实有关输入签名,这意味着对于文档文字样式的 Web 服务,端点将无法区分您实际发出的请求类型.尝试传递两个不同的元素名称.

EDIT 1: This may also have to do with the fact that getAllPersoonData and getAllLessenData have the same input signature, which means that, for document literal style web services, the endpoint won't be able to distinguish what kind of request you're actually making. Try passing two different element names.

编辑 2:此外,为这些消息提供不同的签名将允许您将 getPersoonID 放在类型定义中,以便您只有一个消息部分.现在,如果你查看 Customer.wsdl 你有:

EDIT 2: Also, giving these messages different signatures would allow you to put getPersoonID within the type definition so that you only have one message part. Right now, if you look in Customer.wsdl you have:

<wsdl:message name="getPersoonIDCustomerID">
    <wsdl:part name="body" element="ns:UserCredentials"/>
    <wsdl:part name="getPersoonID" type="xs:int"/>
</wsdl:message>

您不应该在文档文字消息中包含多个部分.

You should not have more than one part in a document-literal message.

编辑 3:如果您不想为您拥有的每个函数定义一个新元素,那么您必须切换到 RPC 文字,它将请求包装在 wsdl:operation名称.如果这可以解决除 .NET 之外的所有问题,那么您可以尝试我的 SO 帖子诱使 .NET 读取 RPC-literal Web 服务.

EDIT 3: If you don't want to define a new element for each function that you have, then you would have to switch to RPC literal, which wraps the request in the wsdl:operation name. If this would fix everything except .NET, then you could try my SO post on coaxing .NET into reading RPC-literal web services.

这篇关于WSDL PHP 函数返回 null 而其他函数返回预期结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆