Мои извинения, у вас, похоже, есть действительная проблема на вашей руке.Ключ в следующем: Почему косая черта - это экранируемый символ в JSON? и его дублируемая цель, JSON: почему экранированные косые черты экранированы? .Поскольку разрешены как неэкранированные, так и экранированные косые черты, Ruby решил не избегать их, а PHP решил избежать их, и оба подхода верны.
(За исключением: говорить об этом немного сложно, потому что\
является escape-символом как для строкового литерала, так и для строк JSON. Таким образом, в этом ответе я позабочусь о puts
(или echo
/ print_r
) всех значениях, чтобы увидеть строки, которыене имеют строкового литерала, экранирующего обратную косую черту, только те, которые фактически присутствуют в строках.)
Таким образом, JSON {"url":"http:\/\/example.com\/test"}
является представлением хеша Ruby { 'url' => 'http://example.com/test' }
, где экранированные косые черты (как PHP json_encode
сделал бы это).Ruby's to_json' would render that as
{"url": "http://example.com/test"}`:
# 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"}
С другой стороны, {"url":"http:\\/\\/example.com\\/test"}
(представленный в Ruby и PHP как строка '{"url":"http:\\\\/\\\\/example.com\\\\/test"}'
) является представлением хеша Ruby{ 'url' => 'http:\/\/example.com\/test' }
, где есть фактические обратные слэши, но слэши не экранированы. PHP json_encode
будет отображать это значение как {"url":"http:\\\/\\\/example.com\\\/test"}
.
# 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
имеет опциюзапретить PHP по умолчанию для экранирования обратной косой черты:
# PHP
echo json_encode('/'); # "\/"
echo json_encode('/', JSON_UNESCAPED_SLASHES); # "/"
Ruby не имеет аналогичной опции для принудительного экранирования косой черты, но, поскольку косая черта не имеет специального значения в JSON, мы можем просто заменить /
вручнуюс \/
:
# Ruby
puts '/'.to_json # "/"
puts '/'.to_json.gsub('/', '\/') # "\/"