由于我似乎无法解决的问题,我目前正遇到一堵巨大的墙。
问题在于,当您通过Facebook支付平台(Facebook javascript sdk)发出付款时,它会将数据发送到您的回调页面,该页面应该在后台处理付款。
这一切都很不错,但有一个问题:facebook使用的订单ID是64位ID,而我的服务器是32位服务器,因此当它被保存到回调中的变量时,它会丢失ID的精度页。这最终导致最终无法获得正确的order_ID,因为它无法保存ID。
此论坛的几个页面已对此问题进行了描述,例如:
facebook credit callback, order_id changes format changes after moving to a new server
和
PHP: Converting a 64bit integer to string
然而,在这两个页面上都没有解决问题的方法,我似乎无法解决这个问题。 我试图将facebook发送到我的回调页面的json数据转换为字符串数据而不是带有整数的数组(这发生在facebook提供的基本代码中),但我无法让它工作。
看到其他人已经克服了这个问题(无需将所有内容迁移到64位服务器),我想知道如何。
有人能够对这个问题有所了解吗?
编辑: 我已经尝试过转换为字符串,这是一个被调用来解码json数据的标准facebook代码(由facebook提供的代码):
$request = parse_signed_request($_POST['signed_request'], $app_secret);
这会调用函数parse_signed_request,它执行:
function parse_signed_request($signed_request, $secret) {
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
$sig = base64_url_decode($encoded_sig);
$data = json_decode(base64_url_decode($payload), true);
if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') {
error_log('Unknown algorithm. Expected HMAC-SHA256');
return null;
}
// check sig
$expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true);
if ($sig !== $expected_sig) {
error_log('Bad Signed JSON signature!');
return null;
}
return $data;
}
此函数解码来自facebook的加密json数据(使用app secret),并将json数据解码为PHP数组。
该函数使用以下函数(确切地说:
function base64_url_decode($input) {
return base64_decode(strtr($input, '-_', '+/'));
}
现在,上面的代码会导致订单ID无法正确保存,并且会失去其精度,从而导致ID如下:4.8567130814993E + 14
我试图使用以下函数以某种方式将json数据解码为字符串(因此64位整数ID不会失去其精度),但无济于事:
function largeint($rawjson) {
$rawjson = substr($rawjson, 1, -1);
$rawjson = explode(',' , $rawjson);
array_walk($rawjson, 'strfun');
$rawjson = implode(',', $rawjson);
$rawjson = '{' . $rawjson . '}';
$json = json_decode($rawjson);
return $json;
}
function strfun(&$entry, $key) {
$data = explode(':', $entry);
if (FALSE === strpos($data[1], '"')) {
$data[1] = '"' . $data[1] . '"';
$entry = implode(':', $data);
}
}
编辑(Eugenes回答):
如果我在使用json_decode使其成为php变量之前尝试修改JSON数据,我应该使用preg_replace函数吗? 以下是发送到回调页面以启动付款流程的初始JSON数据的示例。 在这里你已经可以看到问题所在(这是在使用json_decode之后,id和其他数据失去了它们的精度)。 ID被修改为不反映任何实际数据。 如果您比较顶部的买方ID和底部的用户ID,您可以看到精度丢失。
Array
(
[algorithm] => HMAC-SHA256
[credits] => Array
(
[buyer] => 1.0055555551318E+14
[receiver] => 1.0055555551318E+14
[order_id] => 5.2555555501665E+14
[order_info] => {"item_id":"77"}
[test_mode] => 1
)
[expires] => 1358456400
[issued_at] => 1358452270
[oauth_token] => AAAH4s2ZCCEMkBAPiGSNsmj98HNdTandalotmoredata
[user] => Array
(
[country] => nl
[locale] => nl_NL
[age] => Array
(
[min] => 21
)
)
[user_id] => 100555555513181
)
编辑#3:
我已尝试以下操作使JSON数据中的所有整数看作字符串,但这会导致facebook平台出错。然而它确实将整数更改为字符串,因此我不会失去精度(太糟糕了,现在没有其他工作xD)
preg_replace('/([^\\\])":([0-9]{10,})(,|})/', '$1":"$2"$3', $a)
答案 0 :(得分:1)
您运行的是哪个版本的PHP?
如果您运行的是支持JSON“JSON_BIGINT_AS_STRING”选项的PHP版本,那么这可能就是您的答案。您可能必须在使用json_decode添加该选项的任何地方修改其库。见http://php.net/manual/en/function.json-decode.php
如果您的PHP版本不支持JSON_BIGINT_AS_STRING,那么您的选项仅限于:
hacky选项:对JSON字符串执行某种正则表达式操作,因为它从FB API返回并用双引号包装那么大的内联,这样它们就可以解码为字符串而不是大的int。
理想选择:咬紧牙关并迁移到64位环境。从长远来看,它可以帮助您避免许多麻烦。