首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么__soapcall会将xs:decimal转换为"true"?

为什么__soapcall会将xs:decimal转换为"true"?
EN

Stack Overflow用户
提问于 2019-05-12 14:56:30
回答 2查看 48关注 0票数 0

我使用的是PHP Soap。

这是从__getLastRequest()获得的代码片段。我不明白为什么"Version“是"true”,而不是我设置的值:"1.0"?

事实上,我不仅在版本上有问题,在TimeStamp上也有问题。我为它设置的值是\DateTime::ATOM。不确定为什么它会出现在2019年。

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

SOAP服务器拒绝接受我的XML,SoapFault如下所示。我已经在SOAP中手动形成了XML,并发布了,一切都按预期工作。然而,当我使用PHP Soap时,我得到了这个SoapFault,唯一的两个不同之处是版本和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中,TimeStamp和版本的定义如下:

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并手动创建XML和post时,一切都按预期工作。

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

提前感谢您的帮助!

EN

回答 2

Stack Overflow用户

发布于 2019-05-13 01:30:30

很高兴找到了另一种方法来调用这些SOAP API,而不是使用类和SoapClient

使用此Stackoverflow post中的this technique -改为使用Curl。真是个救命稻草!

所有工作都很好!

票数 0
EN

Stack Overflow用户

发布于 2022-01-27 12:04:03

这可能会帮助其他遇到同样问题的人,在PHP7.2中,SoapClient会将十进制值转换为true。输入17.017.0017,017,00或仅输入17都无关紧要。迁移到PHP7.4为我解决了这个问题。似乎在PHP7.2的SoapClient中有一个小bug。

希望这对任何人都有帮助!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56096897

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档