我需要对一些包含URL字符串的哈希进行编码。我使用to_json方法,并且每个斜杠前面都需要反斜杠(因为PHP会打印这样的字符串)。 例如:
hash = {"url":"http:\\/\\/example.com\\/test"}
hash.to_json
结果是
{:url=>"http:\\/\\/example.com\\/test"}
在需要时(PHP的json_encode返回带有单个反斜杠的字符串)。
{:url=>"http:\/\/example.com\/test"}
在编码的情况下,与PHP一样,保留字符串非常重要。因为带有双反斜杠和单反斜杠的字符串会得到不同的结果。
UPD: 问题不在于沟通。我需要使用HMAC(SHA384)对JSON进行编码。当我使用URL字符串时,结果在PHP和Ruby中是不同的。如果该字符串不包含反斜杠,则一切正常...
PHP实现引入了反斜杠。 PHP使用的JSON看起来{"url":"http:\/\/example.com\/test"}
如此,而Ruby的JSON是{"url":"http:\\/\\/example.com\\/test"}
答案 0 :(得分:2)
很抱歉,您的手边似乎确实有问题。关键是这样的:Why is the slash an escapable character in JSON?及其重复目标JSON: why are forward slashes escaped?。由于未转义的斜杠和转义的斜杠都允许,因此Ruby选择不转义,而PHP选择转义,这两种方法都是正确的。
(此外:谈论这个问题有点复杂,因为\
是字符串文字和JSON字符串的转义字符。因此,在这个答案中,我要注意{{1 }}(或puts
/ echo
)的所有值,以查看不包含字符串文字反斜杠的字符串转义,而仅看到字符串中实际存在的反斜杠。)
因此,JSON print_r
是Ruby哈希{"url":"http:\/\/example.com\/test"}
的表示形式,其中的斜杠被转义了(就像PHP的{ 'url' => 'http://example.com/test' }
那样)。 Ruby的json_encode
{“ url”:“ http://example.com/test”}`:
to_json' would render that as
另一方面,# Ruby
json1 = '{"url":"http:\/\/example.com\/test"}'
puts json1 # => {"url":"http:\/\/example.com\/test"}
puts JSON.parse(json1) # => {"url"=>"http://example.com/test"}
puts JSON.parse(json1).to_json # => {"url":"http://example.com/test"}
# PHP
$json1 = '{"url":"http:\/\/example.com\/test"}';
echo $json1; # {"url":"http:\/\/example.com\/test"}
print_r(json_decode($json1)); # stdClass Object
# (
# [url] => http://example.com/test
# )
echo json_encode(json_decode($json1)); # {"url":"http:\/\/example.com\/test"}
(在Ruby和PHP中表示为字符串{"url":"http:\\/\\/example.com\\/test"}
)是Ruby哈希'{"url":"http:\\\\/\\\\/example.com\\\\/test"}'
的表示,其中存在实际的反斜杠,但斜杠不逃脱。 PHP的{ 'url' => 'http:\/\/example.com\/test' }
会将此值呈现为json_encode
。
{"url":"http:\\\/\\\/example.com\\\/test"}
PHP # Ruby
json2 = '{"url":"http:\\\\/\\\\/example.com\\\\/test"}'
puts json2 # => {"url":"http:\\/\\/example.com\\/test"}
puts JSON.parse(json2) # => {"url"=>"http:\\/\\/example.com\\/test"}
puts JSON.parse(json2).to_json # => {"url":"http:\\/\\/example.com\\/test"}
# PHP
$json2 = '{"url":"http:\\\\/\\\\/example.com\\\\/test"}';
echo $json2; # {"url":"http:\/\/example.com\/test"}
print_r(json_decode($json2)); # stdClass Object
# (
# [url] => http:\/\/example.com\/test
# )
echo json_encode(json_decode($json2)); # {"url":"http:\\\/\\\/example.com\\\/test"}
有一个选项可以防止PHP默认情况下转义反斜杠:
json_encode
Ruby没有类似的选项来强制转义斜杠,但是由于斜杠在JSON中没有特殊含义,因此我们可以将# PHP
echo json_encode('/'); # "\/"
echo json_encode('/', JSON_UNESCAPED_SLASHES); # "/"
手动替换为/
:
\/
答案 1 :(得分:1)
如果不想处理转义的反斜杠,请在字符串周围使用单引号。
hash = { url: 'http:\/\/example.com\/test' }
json = hash.to_json
puts json
# => {"url":"http:\\/\\/example.com\\/test"}
快速提醒一下:在JSON中,反斜杠必须转义,因为它们被视为控制字符。
这样,当PHP解析此JSON文档时,您将在每个斜杠之前使用一个反斜杠获得字符串。
答案 2 :(得分:0)
您的问题背后的问题可能是真正的问题。我不确定,因为您的问题对我来说还不是很清楚,所以我在这里用我的答案进行猜测/假设。
我在这里的假设是,您想使用json在ruby和php之间进行通信。
好吧,在这种情况下,您不必有任何问题(反斜线)。
让红宝石 .to_json ( JSON.generate(..))和 JSON.parse(..)解决红宝石部分并让 json_encode()和 json_decode()解决php部分,就完成了。
所以是红宝石:
-不要使用多余的转义反斜杠,让 .to_json 为您解决这个问题
-使用您将在浏览器中键入的文字网址字符串,如下所示:
hash = {"url":"http://example.com/test"} # hash is a ruby object
puts hash.to_json # => {"url":"http://example.com/test"} is JSON (string)
然后用php :
var_dump( json_decode('{"url": "http://example.com/test"}') );
给您
object(stdClass)#1 (1) {
["url"]=>
string(23) "http://example.com/test"
}
var_dump( json_decode('{"url": "http:\/\/example.com\/test"}') );
给您
object(stdClass)#1 (1) {
["url"]=>
string(23) "http://example.com/test"
}
请注意,两个JSON字符串最终都将在PHP中正确解析,并最终作为普通的PHP对象
答案 3 :(得分:0)
尝试如下
hash = {"url":"http:\\/\\/example.com\\/test"}
hash[:url] = hash[:url].delete("\\")
hash.to_json #"{\"url\":\"http://example.com/test\"}"
希望对您有帮助