为什么__soapcall会将xs:decimal转换为“ true”?

时间:2019-05-12 06:56:30

标签: php soap wsdl soap-client

我正在使用PHP Soap。

这是从__getLastRequest()获得的代码段。我对为什么“版本”显示为“ true”而不是我设置的值“ 1.0”感到困惑?

实际上,我不仅对Version有问题,而且TimeStamp也有问题。我为此设置的值是\ DateTime :: ATOM。不确定为什么会在2019年问世。

<ns1:OTA_CruiseSailAvailRQ TimeStamp="2019" Version="true" 

SOAP服务器拒绝接受我的XML,SoapFault读取如下。我已经在SOAP UI中手动形成XML并发布了,并且一切正常。但是,当我使用PHP Soap进行此操作时,会出现SoapFault信息,唯一不同的两件事是Version和TimeStamp。

 [faultstring] => 
Internal Error (from server)

    [faultcode] => 
env:Receiver

这里有更多的XML:

<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://www.opentravel.org/OTA/2003/05/alpha" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="http://services.rccl.com/Interfaces/SailingList">

 <env:Body>

   <ns2:getSailingList>

     <ns1:OTA_CruiseSailAvailRQ TimeStamp="2019" Version="true"


在WSDL中,时间戳和版本的定义如下:

WSDL

<xs:attribute name="Version" type="xs:decimal" use="required">
            <xs:annotation>
                <xs:documentation xml:lang="en">For all OTA versioned messages, the version of the message is indicated by a decimal value.</xs:documentation>
            </xs:annotation>
</xs:attribute>

<xs:attribute name="TimeStamp" type="xs:dateTime" use="optional">
            <xs:annotation>
                <xs:documentation xml:lang="en">Indicates the creation date and time of the message in UTC using the following format specified by ISO 8601; YYYY-MM-DDThh:mm:ssZ with time values using the 24 hour clock (e.g. 20 November 2003, 1:59:38 pm UTC becomes 2003-11-20T13:59:38Z).</xs:documentation>
            </xs:annotation>
</xs:attribute>

这是我设置值并启动SOAP调用的方式

$test = new MyNamespace\OTA_CruiseSailAvailRQ();
$d = new DateTime('NOW');

$test->setTimeStamp($d);
$test->setVersion(1.0);    


$sailCall = new MyNamespace\Cruise_FIT_External(['trace' => 1,
                                   'exception' => 0,
                                   'login' => 'xxxxxxx', 
                                   'password' => 'xxxxxxxx',
                                  'soap_version' => SOAP_1_2]);


$resp = $sailCall->getSailingList(new MyNamespace\getSailingList($test));

我已经使用Wsdl2PhpGenerator从我的WSDL中生成了我的类。这就是为什么您看到Cruise_FIT_External而没有看到SoapClient的直接实例的原因。但是它扩展了SoapClient。所以我们在那里很好。

namespace MyNamespace;

class Cruise_FIT_External extends \SoapClient
{
    /**
     * @param getSailingList $parameters
     * @return getSailingListResponse
     */
    public function getSailingList(getSailingList $parameters)
    {

      return $this->__soapCall('getSailingList', array($parameters));
    }
}

这是定义setTimestamp和SetVersion函数的方式。同样,这是Wsdl2PhpGenerator输出的代码。所以我认为很好。


namespace MyNamespace;

class OTA_CruiseSailAvailRQ
{

    /**
     * @var float $Version
     */
    protected $Version = null;

    /**
     * @var \DateTime $TimeStamp
     */
    protected $TimeStamp = null;

    /**
     * @param \DateTime $TimeStamp
     * @return \MyNamespace\OTA_CruiseSailAvailRQ
     */
    public function setTimeStamp(\DateTime $TimeStamp)
    {
      $this->TimeStamp = $TimeStamp->format(\DateTime::ATOM);
      return $this;
    }


    /**
     * @return \DateTime
     */
    public function getTimeStamp()
    {
      if ($this->TimeStamp == null) {
        return null;
      } else {
        try {
            return DateTime::createFromFormat(\DateTime::ATOM, $this->TimeStamp); 
          // this below was the original line. didn't work. changed it to the line above. that didn't work either.
          //return new \DateTime($this->TimeStamp); 
           return $this->TimeStamp;
        } catch (\Exception $e) {
          return false;
        }
      }
    }

    /**
     * @return float
     */
    public function getVersion()
    {
      return $this->Version;
    }

    /**
     * @param float $Version
     * @return \MyNamespace\OTA_CruiseSailAvailRQ
     */
    public function setVersion($Version)
    {
      $this->Version = $Version;
      return $this;
    }

如果解决了此问题,则预期输出应如下所示。我知道这可行,因为当我使用SOAP UI并手动创建XML并发布时,一切都按预期工作。

<ns1:OTA_CruiseSailAvailRQ TimeStamp="2019-05-11T15:30:41-05:00" Version="1.0" 

在此先感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

大喜过望,找到了另一种方法来调用这些SOAP API,而不是使用类和SoapClient

此Stackoverflow帖子中使用了this technique-改用Curl。如此救命的人!

一切正常!