219

I'm pulling JSON from Instagram:

$instagrams = json_decode($response)->data;

Then parsing variables into a PHP array to restructure the data, then re-encoding and caching the file:

file_put_contents($cache,json_encode($results));

When I open the cache file all my forward slashes "/" are being escaped:

http:\/\/distilleryimage4.instagram.com\/410e7...

I gather from my searches that json_encode() automatically does this...is there a way to disable it?

AbraCadaver
  • 78,200
  • 7
  • 66
  • 87
Michael C.
  • 2,430
  • 3
  • 17
  • 20
  • 2
    It is optional: "the characters that must be escaped: quotation mark, reverse solidus, and the control characters (U+0000 through U+001F). Any character may be escaped." – ThiefMaster Apr 18 '12 at 13:29

4 Answers4

382

is there a way to disable it?

Yes, you only need to use the JSON_UNESCAPED_SLASHES flag (PHP 5.4+).

!important read before: https://stackoverflow.com/a/10210367/367456 (know what you're dealing with - know your enemy: DO NOT USE in web/html context - CLI, unless CGI, might be fine thought, if they think they need it in JSON HTTP context for readability purposes, they have a different problem)

json_encode($str, JSON_UNESCAPED_SLASHES);

If you don't have PHP 5.4 at hand (you certainly already asserted the warning above), pick one of the many existing functions and modify them to your needs, e.g. http://snippets.dzone.com/posts/show/7487 (archived copy).

Example Demo

<?php
/*
 * Escaping the reverse-solidus character ("/", slash) is optional in JSON.
 *
 * This can be controlled with the JSON_UNESCAPED_SLASHES flag constant in PHP.
 *
 * @link http://stackoverflow.com/a/10210433/367456
 */    

$url = 'http://www.example.com/';

echo json_encode($url), "\n";

echo json_encode($url, JSON_UNESCAPED_SLASHES), "\n";

Example Output:

"http:\/\/www.example.com\/"
"http://www.example.com/"
hakre
  • 193,403
  • 52
  • 435
  • 836
  • 6
    This answer is grate but JSON Encode as standard you should leave it as escaped and then in the reciving end undo the escaping php's `strip_slashes` and for JS http://phpjs.org/functions/stripslashes/ – Barkermn01 May 23 '14 at 09:07
  • 1
    @MartinBarker: This might have been a problem only with PHP 5.2.1: http://3v4l.org/0AahO - The JSON is valid in both cases. – hakre May 03 '15 at 07:53
  • @MartinBarker For some strange reason forward slash was not stripping on the receiving end with stripslashes(), str_replace() or preg_replace(). Before I found this answer, I hacked together a way to get rid of the slash by using urlencode() and then replacing %2F. I'm using PHP7 on Windows. Not sure if there is a bug some where, but magic quotes is not even included in PHP7 so it's better to avoid the hackery by simply disabling the slashes. – Sami Fouad Mar 12 '17 at 07:11
  • @SamiFouad: Even with the slashed, it is correct JSON and should not create any problems (unless the receiver is not handling JSON properly, see http://json.org/ , especially the *char* description on the right side which explicitly names `\/` as valid escape sequence for `/`), see https://stackoverflow.com/a/10210367/367456 as well. – hakre Jul 26 '17 at 23:16
  • 5
    **Ugly PHP!** the `JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES` must be default, not (strange) option... How to say it to php-developers? – Peter Krauss Aug 14 '17 at 16:58
  • @PeterKrauss: No, it must not be default. This is not a question of uglyness but what is better. Unicode is fine, escaped slashes are better. [Escaping forward slashes is a good thing](https://stackoverflow.com/a/10210367/367456). – hakre Aug 14 '17 at 17:56
  • 1
    Thanks @hakre! Well, it is a manifest :-) https://stackoverflow.com/a/45681613/287948 – Peter Krauss Aug 14 '17 at 19:23
  • When using JSON with JavaScript it seems necessary to escape forward slashes. When using any other language it seems to be more of an annoyance. – Matt K Jan 16 '20 at 22:09
  • Note that using `JSON_UNESCAPED_SLASHES` is always okay if you encode the output for the correct context (as you should). However, using `JSON_UNESCAPED_UNICODE` is safe only if your binary data has the same encoding as the output binary data. With encoded unicode, the output data is ASCII compatible. That said, if you can handle encodings correctly, `JSON_UNESCAPED_UNICODE` is safe, too. – Mikko Rantalainen Dec 02 '22 at 12:06
  • 1
    @MikkoRantalainen: Yes, appplies to both as JSON's own encoding is only UTF-8. The devil is in the detail in two scopes: HTML and Javascript. Considering the audience of this site, and given that most consuming users have still problems to figure out which encoding it is (if not being confronted with one for the first time), it may not be necessary, but it can be safely ignored. There was a quirk in the defaults in some PHP version regarding this, but its fixed nowadays. – hakre Dec 02 '22 at 16:04
  • PHP used to have misfeature called "magic quotes", too, which was based on similarly poor idea that you can do *some kind of encoding* and hope things end up okay. That's not safe. Even in case of HTML, there are small differences how text is encoded in attribute value vs text between the tags. One size fits all encoding will not work and no support for it should be enabled by default. It's better to crash sooner than have hard to find security vulnerabilities because of wrong encoding, IMO. – Mikko Rantalainen Dec 02 '22 at 16:16
56

Yes, but don't - escaping forward slashes is a good thing. When using JSON inside <script> tags it's necessary as a </script> anywhere - even inside a string - will end the script tag.

Depending on where the JSON is used it's not necessary, but it can be safely ignored.

Community
  • 1
  • 1
ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
  • 5
    So will javascript automatically remove the backslashes when it pulls in the json, or this something I need to specify? – Michael C. Apr 18 '12 at 13:30
  • 5
    It will automatically handle it. Like in many other languages, escaping characters without a special meaning in the language just leaves those characters alone. – ThiefMaster Apr 18 '12 at 13:31
  • 19
    @MichaelC. In JSON the string value `"\/"` is exactly the same as string value `"/"` - and a working JSON parser will treat it as such. The same rule applies to javascript strings, so feeding JSON as a javascript code will not have any troubles either. I am surprised PHP even has the `JSON_UNESCAPED_SLASHES` flag. – Esailija Aug 10 '12 at 18:19
  • 6
    But what if one is encoding the data into JSON and then storing them into a database column? If the program has some mechanism to escape characters for database's sake, wouldn't this feature be very inconvenient since now the slashes are being double-escaped? – Xavier_Ex Sep 22 '14 at 17:21
  • 3
    @Esailija Because JSON has become so ubiquitous, it may not necessarily always be used with JavaScript. I am creating an HTTP API and the returned JSON may be parsed in JS in a NodeJS app, or it may be read in PHP by a web server, or it may be parsed in Swift in an iOS app. It's better not to lean towards JS-specific solutions/behaviours. – Sami Fouad Mar 12 '17 at 07:17
  • 7
    Dumping JSON into script tags without an encoding step on the assumption that the JSON implementation was escaping slashes seems like a practice that is certain to eventually bite you. – Ryan Jun 23 '17 at 04:39
  • 1
    Please upvote this answer to the sky. Mine still gets hits which might be deserved but it is short-sighted when compared with ThiefMasters addition --- esp. about the note on Javascript where a lot of JSON ends at the end from a PHP script as the browser is targeted as client system. Every developer who cares, please upvote Thiefmasters answer, it costs you nothing. Thanks. (This will make it more obvious for by-surfing visitors) – hakre Jul 26 '17 at 23:22
  • The *correct* way to handle user inputted data to be inserted between ` – Mikko Rantalainen Dec 02 '22 at 12:02
4

On the flip side, I was having an issue with PHPUNIT asserting urls was contained in or equal to a url that was json_encoded -

my expected:

http://localhost/api/v1/admin/logs/testLog.log

would be encoded to:

http:\/\/localhost\/api\/v1\/admin\/logs\/testLog.log

If you need to do a comparison, transforming the url using:

addcslashes($url, '/')

allowed for the proper output during my comparisons.

Squadrons
  • 2,467
  • 5
  • 25
  • 36
-2

I had to encounter a situation as such, and simply, the

str_replace("\/","/",$variable)

did work for me.

  • 6
    This is **NOT** correct, `str_replace("\\/","/",$variable)` or `str_replace('\/','/',$variable)` – a55 Feb 28 '21 at 13:10
  • @a55 Even with a single quoted string, you still have to escape backslashes: ```str_replace('\\/', '/', $v);``` – Jordan Jan 02 '23 at 03:36