Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/251.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/apache/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将嵌套的json对象转换为php字符串而不剥离值_Php_Json - Fatal编程技术网

将嵌套的json对象转换为php字符串而不剥离值

将嵌套的json对象转换为php字符串而不剥离值,php,json,Php,Json,我正在接收一个带有以下JSON对象的HTTP Post: {"notification":{"version":6.0,"attemptCount":0,"role":"VENDOR","site":"nicholeen","receipt":"********","currency":"USD","transactionType":"TEST","transactionTime":1406070122781,"paymentMethod":"VISA","totalProductAmount"

我正在接收一个带有以下JSON对象的HTTP Post:

{"notification":{"version":6.0,"attemptCount":0,"role":"VENDOR","site":"nicholeen","receipt":"********","currency":"USD","transactionType":"TEST","transactionTime":1406070122781,"paymentMethod":"VISA","totalProductAmount":1.00,"totalTaxAmount":0.00,"totalShippingAmount":0.00,"customer":{"shipping":{"firstName":"TEST","lastName":"USER","fullName":"Test User","email":"testuser@somesite.com","address":{}},"billing":{"firstName":"TEST","lastName":"USER","fullName":"Test User","email":"testuser@somesite.com","address":{}}},"lineItems":[{"itemNo":"1","productTitle":"A passed in title","shippable":false,"recurring":false,"customerProductAmount":1.00,"customerTaxAmount":0.00}]},"verification":"2745A502"}
我需要将“notification”JSON对象转换为分配给PHP变量的JSON字符串,而不会丢失任何数据,包括小数

目前,我正在使用
$IPN\u raw=file\u get\u contents('php://input');。
然后我将json_解码为一个PHP变量,然后使用json_encode重新编码通知部分。代码如下:

$ipn_raw = file_get_contents('php://input');
$ipn = json_decode($ipn_raw);
$notification = $ipn['notification'];
$result = json_encode($notification);
但是,结果删除了一些值,给出了以下内容:

{"version":6,"attemptCount":0,"role":"VENDOR","site":"nicholeen","receipt":"********","currency":"USD","transactionType":"TEST","transactionTime":1406095846441,"paymentMethod":"VISA","totalProductAmount":1,"totalTaxAmount":0,"totalShippingAmount":0,"customer":{"shipping":{"firstName":"TEST","lastName":"USER","fullName":"Test User","email":"testuser@somesite.com","address":[]},"billing":{"firstName":"TEST","lastName":"USER","fullName":"Test User","email":"testuser@somesite.com","address":[]}},"lineItems":[{"itemNo":"1","productTitle":"A passed in title","shippable":false,"recurring":false,"customerProductAmount":1,"customerTaxAmount":0}]}
您可以看到6.0版现在只是6版,totalProductAmount是1.00,现在是1,以此类推

如何在结果中不更改任何值的情况下执行此操作

谢谢

根据请求,这里有一些额外的背景信息,说明为什么我需要一切都保持原样。Clickbank为我提供了以下信息,以便创建必要的SHA 1哈希,以验证我从他们那里收到的版本6 IPN(请参阅)

1) 使用JSON库/DSL从IPN中提取“通知”JSON对象。 2) 将“通知”JSON对象转换为JSON字符串。字符串应该以大括号{开头,以大括号}结尾,因为它是JSON对象的表示形式。 3) 将密钥直接附加到通知对象的结束大括号后的字符串上。没有空格或分隔符。 4) SHA 1散列在步骤3中创建的字符串。 5) 取步骤4中创建的哈希的前8个字符。这是v6 IPN中“验证”字段的值

如果需要,我可以为其余步骤提供所有代码,但目前我唯一遇到问题的部分是将通知对象本身放入字符串中。

您要问的是什么(考虑到您正在对JSON对象的字符串表示进行散列),您需要通过字符串操作方法(例如regex)提取JSON的相关部分:

这将在开始时将所有内容剥离到第二个大括号,从最后一个大括号开始剥离所有内容。(但它显然只有在JSON具有这种精确格式的情况下才起作用,即通知是唯一的嵌套对象、第一个对象以及其后的所有对象都不包含
}
(尤其是验证代码))



关于这一点,似乎有一个“bug”报告:,尽管字符串化
6.0
似乎是预期的行为,JavaScript也做了同样的事情。另请参见此相关问题:

问题是:从值的角度来看,
6.0
6
都是相同的浮动。因此,在解码时,PHP将丢失此十进制格式的点数。因此,在您第一次调用
json\u decode()
时,您将丢失关于小数点数量的数据

解决的方法可能是将您的值用quites封装在原始源json中,将它们转换成字符串并以该格式存储在PHP中。就像:

$jsonRaw = '{"notification":{"version":6.0,"attemptCount":0,"role":"VENDOR","site":"nicholeen","receipt":"********","currency":"USD","transactionType":"TEST","transactionTime":1406070122781,"paymentMethod":"VISA","totalProductAmount":1.00,"totalTaxAmount":0.00,"totalShippingAmount":0.00,"customer":{"shipping":{"firstName":"TEST","lastName":"USER","fullName":"Test User","email":"testuser@somesite.com","address":{}},"billing":{"firstName":"TEST","lastName":"USER","fullName":"Test User","email":"testuser@somesite.com","address":{}}},"lineItems":[{"itemNo":"1","productTitle":"A passed in title","shippable":false,"recurring":false,"customerProductAmount":1.00,"customerTaxAmount":0.00}]},"verification":"2745A502"}';

$jsonRaw = preg_replace('/(\b)([0-9]+\.[0-9]+)(\b)/', '$1"$2"$3', $jsonRaw);
$jsonObj = json_decode($jsonRaw);
因此,现在您的对象将把您的值存储为字符串,这不会导致小数点丢失。当然,对于解码,您需要做相反的事情:

$notification = $jsonObj->notification;
$result       = json_encode($notification);
$result       = preg_replace('/"([0-9]+\.[0-9]+)"/', '$1', $result);

但这有一个缺陷:因为您将丢失关于什么是实际字符串和什么是浮动的数据。因此,如果您的原始json包含类似于
“6.00”
的字符串,并且它是字符串,那么这种转换将丢失该信息并使该值浮动。因此,如果您的数据以这种形式包含这样的字符串,那么-是的,这不是一种方法(但我怀疑没有实现自己的json解析器,是否有一种简单的方法)

对于任何感兴趣的人,我最后使用的是:

$json_ipn = preg_replace('({"notification":|,"verification"([\s\S]*))', '', $ipn_raw);

您知道
6.0
6
只是同一个数字的两个不同表示形式。您甚至可以尝试使用PHP:
var_dump(6.0==6);//将打印为真
是,knittl。我知道他们是同一个代表;但是,我需要有完全相同的输出,以便为上面没有提到的另一个步骤生成匹配的SHA 1哈希。然后,您应该在问题中提及所有必要的细节;)输出中的空白是什么?JSON字符串
{“v”:1}
{“v”:1}
也描述了相同的对象。我不确定空格是否会影响SHA1散列的生成。在加密算法中,即使是字节更改也会失败,当然,对于嵌套结构(OP有)@AlmaDo:为什么OP的JSON字符串会失败?我在回答中明确提到了此方法的注意事项。通知不是唯一的嵌套对象。。。你有“顾客”和其他几个人。这会成为一个问题吗?@deggertsen:很可能。也许你可以修改正则表达式。您还应该记住,浮点值不能表示每个十进制值(例如,
1.1
不能用二进制精确表示,只能存储近似值)。如果你觉得不舒服,你甚至可以编写一个计算大括号并忽略字符串中大括号的解析器来提取通知对象。@deggertsen:请参阅我的答案更新。JavaScript的行为方式与PHP相同,将
x.0
值表示为整数。谢谢。这很有帮助。看起来一团糟。。。clickbank即时通知服务的第4版要简单得多。有没有一种方法可以使用javascript实现这一点,然后将结果保存到一个变量中?我不确定您想在js中做什么,但这里的问题是PHP方面(是PHP解析器去除十进制零)
$json_ipn = preg_replace('({"notification":|,"verification"([\s\S]*))', '', $ipn_raw);