问题 PHP SOAP问题:未将对象引用设置为对象的实例


我正在尝试构建一个接口 https://ws.farebuzz.com/FlightGateway.asmx?WSDL 使用php和SoapClient类。

我设法克服了身份验证标题,但是当我尝试调用方法时我被卡住了......我总是得到:

未捕获的SoapFault异常:[soap:Server]服务器无法处理请求。 --->对象引用未设置为对象的实例。

我试着像这样(作为对象)调用它:

class SearchFlights{
    public $NumberOfAdults;
        public $ClassOfService;
    public $TypeOfTrip;
    public $FromCity;
    public $ToCity;
}

$parameters = new SearchFlights();
$parameters->NumberOfAdults = 2;
$parameters->ClassOfService = 'ECONOMY';
$parameters->FromCity = 'ECONOMY';
$parameters->ToCity = '1te';
$parameters->TypeOfTrip = 'NONE';
$this->client->SearchFlights($parameters);

并像一个数组:

$parameters = array('ToCity' => 'testttt',...);

但我得到了同样的错误。有人可以帮忙吗?

谢谢

索林


4427
2018-05-27 11:39


起源



答案:


您的WSDL声明必须以这种方式调用它:

$this->client->SearchFlights(array('searchRequest' => $parameters));

请注意 searchRequest 名字是 重要

该服务还有各种强制性输入,您应该确保它们存在。从查看代码开始,您就会遗漏一些代码。

看看吧 FlightSearchRequest 复杂类型在这里。每个参数都有 minOccurs=1 是必须的。

<s:complexType name="FlightSearchRequest">
    <s:sequence>
        <s:element minOccurs="1" maxOccurs="1" name="TypeOfTrip" type="tns:TripType"/>
        <s:element minOccurs="0" maxOccurs="1" name="FromCity" type="s:string"/>
        <s:element minOccurs="0" maxOccurs="1" name="ToCity" type="s:string"/>
        <s:element minOccurs="0" maxOccurs="1" name="ReturnFromCity" type="s:string"/>
        <s:element minOccurs="0" maxOccurs="1" name="ReturnToCity" type="s:string"/>
        <s:element minOccurs="1" maxOccurs="1" name="DepartureDate" type="s:dateTime"/>
        <s:element minOccurs="1" maxOccurs="1" name="ReturnDate" type="s:dateTime"/>
        <s:element minOccurs="1" maxOccurs="1" name="NumberOfAdults" type="s:int"/>
        <s:element minOccurs="1" maxOccurs="1" name="NumberOfChildren" type="s:int"/>
        <s:element minOccurs="1" maxOccurs="1" name="NumberOfInfantsInLap" type="s:int"/>
        <s:element minOccurs="1" maxOccurs="1" name="NumberOfInfantsOnSeat" type="s:int"/>
        <s:element minOccurs="1" maxOccurs="1" name="NumberOfSeniors" type="s:int"/>
        <s:element minOccurs="0" maxOccurs="1" name="AirlinePreference" type="s:string"/>
        <s:element minOccurs="1" maxOccurs="1" name="ClassOfService" type="tns:FlightClass"/>
        <s:element minOccurs="1" maxOccurs="1" name="IsNonStop" type="s:boolean"/>
        <s:element minOccurs="1" maxOccurs="1" name="ConsolidatorFaresOnly" type="s:boolean"/>
        <s:element minOccurs="0" maxOccurs="1" name="FpAffiliate" type="s:string"/>
        <s:element minOccurs="0" maxOccurs="1" name="FpSubAffiliate" type="s:string"/>
    </s:sequence>
</s:complexType>

7
2018-05-30 10:16





试试这个:

$this->client->SearchFlights(array('parameters' => $parameters));

我在尝试访问.net webservice时遇到了问题,这为我解决了这个问题。


5
2017-08-05 18:45





如果我正确理解WSDL,则SearchFlights对象应该包含FlightSearchRequest对象。后者包含参数。

尝试这个:

$parameters->FlightSearchRequest->NumberOfAdults = 2;
$parameters->FlightSearchRequest->ClassOfService = 'ECONOMY';
// etc...
$this->client->SearchFlights($parameters);

0
2018-05-20 11:16





我也很想知道这个问题的答案,最后我知道了这个原因: 我们通过SOAP请求发送的节点应该为我们所知,数据类型以及它们是否是强制的。因此,如果这些节点中的任何一个遵循该WSDL的严格指令不应该被遵循,那么我们将得到错误,该错误将“对象引用未设置为对象的实例”。 我会举一个我面对的例子: 我遇到了同样的问题,我知道我没有向节点发送任何值,除了至少一个值或一次出现,然后我在我的端点验证它,如果成功我发送该值否则为空字符串,这告诉WSDL这至少是1次出现并且有一个值。 最后我解决了这个bug。 这里的基线是,如果节点那些是强制的并且没有完美发送将引发此异常,或者将空字符串发送到这些节点。 谢谢


0
2018-05-30 10:06



缺少必需参数不是导致此问题的原因。这是另一个问题,当第一个问题解决时,这是一个错误的输入结构。 - MrCode


答案:


您的WSDL声明必须以这种方式调用它:

$this->client->SearchFlights(array('searchRequest' => $parameters));

请注意 searchRequest 名字是 重要

该服务还有各种强制性输入,您应该确保它们存在。从查看代码开始,您就会遗漏一些代码。

看看吧 FlightSearchRequest 复杂类型在这里。每个参数都有 minOccurs=1 是必须的。

<s:complexType name="FlightSearchRequest">
    <s:sequence>
        <s:element minOccurs="1" maxOccurs="1" name="TypeOfTrip" type="tns:TripType"/>
        <s:element minOccurs="0" maxOccurs="1" name="FromCity" type="s:string"/>
        <s:element minOccurs="0" maxOccurs="1" name="ToCity" type="s:string"/>
        <s:element minOccurs="0" maxOccurs="1" name="ReturnFromCity" type="s:string"/>
        <s:element minOccurs="0" maxOccurs="1" name="ReturnToCity" type="s:string"/>
        <s:element minOccurs="1" maxOccurs="1" name="DepartureDate" type="s:dateTime"/>
        <s:element minOccurs="1" maxOccurs="1" name="ReturnDate" type="s:dateTime"/>
        <s:element minOccurs="1" maxOccurs="1" name="NumberOfAdults" type="s:int"/>
        <s:element minOccurs="1" maxOccurs="1" name="NumberOfChildren" type="s:int"/>
        <s:element minOccurs="1" maxOccurs="1" name="NumberOfInfantsInLap" type="s:int"/>
        <s:element minOccurs="1" maxOccurs="1" name="NumberOfInfantsOnSeat" type="s:int"/>
        <s:element minOccurs="1" maxOccurs="1" name="NumberOfSeniors" type="s:int"/>
        <s:element minOccurs="0" maxOccurs="1" name="AirlinePreference" type="s:string"/>
        <s:element minOccurs="1" maxOccurs="1" name="ClassOfService" type="tns:FlightClass"/>
        <s:element minOccurs="1" maxOccurs="1" name="IsNonStop" type="s:boolean"/>
        <s:element minOccurs="1" maxOccurs="1" name="ConsolidatorFaresOnly" type="s:boolean"/>
        <s:element minOccurs="0" maxOccurs="1" name="FpAffiliate" type="s:string"/>
        <s:element minOccurs="0" maxOccurs="1" name="FpSubAffiliate" type="s:string"/>
    </s:sequence>
</s:complexType>

7
2018-05-30 10:16





试试这个:

$this->client->SearchFlights(array('parameters' => $parameters));

我在尝试访问.net webservice时遇到了问题,这为我解决了这个问题。


5
2017-08-05 18:45





如果我正确理解WSDL,则SearchFlights对象应该包含FlightSearchRequest对象。后者包含参数。

尝试这个:

$parameters->FlightSearchRequest->NumberOfAdults = 2;
$parameters->FlightSearchRequest->ClassOfService = 'ECONOMY';
// etc...
$this->client->SearchFlights($parameters);

0
2018-05-20 11:16





我也很想知道这个问题的答案,最后我知道了这个原因: 我们通过SOAP请求发送的节点应该为我们所知,数据类型以及它们是否是强制的。因此,如果这些节点中的任何一个遵循该WSDL的严格指令不应该被遵循,那么我们将得到错误,该错误将“对象引用未设置为对象的实例”。 我会举一个我面对的例子: 我遇到了同样的问题,我知道我没有向节点发送任何值,除了至少一个值或一次出现,然后我在我的端点验证它,如果成功我发送该值否则为空字符串,这告诉WSDL这至少是1次出现并且有一个值。 最后我解决了这个bug。 这里的基线是,如果节点那些是强制的并且没有完美发送将引发此异常,或者将空字符串发送到这些节点。 谢谢


0
2018-05-30 10:06



缺少必需参数不是导致此问题的原因。这是另一个问题,当第一个问题解决时,这是一个错误的输入结构。 - MrCode