如何防止 PHP SoapClient 将双精度值转换为科学计数法?
Posted
技术标签:
【中文标题】如何防止 PHP SoapClient 将双精度值转换为科学计数法?【英文标题】:How Can I Prevent PHP SoapClient From Converting Double Value to Scientific Notation? 【发布时间】:2011-08-19 19:03:59 【问题描述】:我正在使用 php SoapClient 并将信用卡号作为值之一传递。这个数字正在通过soapCall 方法转换为指数格式。我正在传递 4321432143274321 并且服务器正在获取 <ccNumber xsi:type="xsd:double">4.3214321432743E+15</ccNumber>
。我尝试将值转换为双精度和字符串无济于事。
我在任何地方都找不到有关此问题的任何提示!我找到的最接近的是:http://www.php.net/manual/en/soapclient.soapcall.php#75078,但“修复”并不是真正的修复。
这是我的代码:
private function SetUpClient()
try
$options = array(
'soap_version'=>SOAP_1_2,
'exceptions'=>true,
'trace'=>1,
'cache_wsdl'=>WSDL_CACHE_NONE
);
$auth->username = $this->_username;
$auth->password = $this->_password;
$authValues = new SoapVar($auth, SOAP_ENC_OBJECT);
$header = new SoapHeader("http://v1.webservices", "authentication", $authValues, false);
$this->_soapClient = new SoapClient( $this->_wsdlUrl );
$this->_soapClient->__setSoapHeaders(array($header));
catch( Exception $ex )
var_dump($ex);
return "An error occured: " . $ex->getMessage();
public function CallWebService($methodName, $arguments)
try
$result = $this->_soapClient->__soapCall($methodName, $arguments);
catch (Exception $e)
echo $e->getMessage();
$result = false;
return $result;
这是正在传递的 $arguments 数组:
Array
(
[memberUid] => 123456789
[items] => 1809,1,N,1821,1,N
[shippingOption] => 40
[name1] => Test15, Juan
[name2] =>
[address1] => 123 Test Street
[address2] =>
[address3] =>
[address4] =>
[city] => Anytown
[stateCode] => NY
[countryCode] => USA
[postalCode] => 12345
[subOrderType] => 041
[entryDate] => 08/18/2011
[ccType] => 3
[ccHolder] => Juan Test
[ccNumber] => 4321432143274321
[ccExpDate] => 01/2014
[externalOrderNumber] =>
[orderSource] =>
)
最后是服务器看到的soap调用部分:
<ns1:createOrder>
<memberUid xsi:type="xsd:string">123456789</memberUid>
<items xsi:type="xsd:string">1809,1,N,1821,1,N</items>
<shippingOption xsi:type="xsd:double">40</shippingOption>
<name1 xsi:type="xsd:string">Test, Juan</name1>
<name2 xsi:type="xsd:string"/>
<address1 xsi:type="xsd:string">123 Test Street</address1>
<address2 xsi:type="xsd:string"/>
<address3 xsi:type="xsd:string"/>
<address4 xsi:type="xsd:string"/>
<city xsi:type="xsd:string">Anytown</city>
<stateCode xsi:type="xsd:string">NY</stateCode>
<countryCode xsi:type="xsd:string">USA</countryCode>
<postalCode xsi:type="xsd:string">12345</postalCode>
<subOrderType xsi:type="xsd:string">041</subOrderType>
<entryDate xsi:type="xsd:string">08/19/2011</entryDate>
<ccType xsi:type="xsd:double">3</ccType>
<ccHolder xsi:type="xsd:string">Juan Test</ccHolder>
<ccNumber xsi:type="xsd:double">4.3214321432743E+15</ccNumber>
<ccExpDate xsi:type="xsd:string">01/2014</ccExpDate>
<externalOrderNumber xsi:type="xsd:string"/>
<orderSource xsi:type="xsd:string"/>
</ns1:createOrder>
【问题讨论】:
我发现了几个类似的问题:bugs.php.net/bug.php?id=43053(我使用的是 PHP 5.3.4)jitterbit.com/PhpBB/viewtopic.php?f=4&p=7319#p7317 【参考方案1】:我找到了解决办法!
我更新了 php.ini 文件中的“精度”设置。我将该值从 14 增加到 16。16 位数是我需要的信用卡号码的最大值。相应地调整您的需求!
【讨论】:
最好简单地使用 ini_set("precision", "16");而不是更改 php.ini 文件。【参考方案2】:将您的 ccNumber 转换为字符串以防止序列化使用浮点表示。
[ccNumber] => 4321432143274321 . ""
【讨论】:
【参考方案3】:您可以使用number_format
函数将数字精确转换为字符串。默认情况下,它使用逗号作为千位分隔符。为避免这种情况,您必须显式覆盖它:
$ccNumber = number_format( 4321432143274321, 0, '', '' );
【讨论】:
这与简单地转换为字符串没有什么不同。该号码被原封不动地传递给 __soapCall()。我确信是 __soapCall() 中的某些东西在进行转换。以上是关于如何防止 PHP SoapClient 将双精度值转换为科学计数法?的主要内容,如果未能解决你的问题,请参考以下文章