9

I'm having troubles getting json_decode to work on a specific string I am receiving.

I have narrowed it down to this line:

"systemNotes[6]": "January 09, 2013 12:52 PM - Test Name - Changed Billing Address 2 From to Shipping First Name: Shipping Last Name: Email Address: Shipping Address: Shipping Address 2: Shipping City: Shipping Zip/Postal: Shipping Country: Shipping State: Phone: Billing First Name: Billing Last Name: Billing Address: Billing Address 2: Billing C"

Copying the json from this question, the problem is not reproducible - but a representative snippet of the original json is here: http://codepad.org/ZzrC7rqQ - and putting that in jsonlint.com gives:

Parse error on line 3:
...  "systemNotes[6]": "January 09, 2013 12
-----------------------^
Expecting 'STRING', 'NUMBER', 'NULL', 'TRUE', 'FALSE', '{', '['

What is wrong with this string such that it's invalid json?

EDIT

I managed to find the exact code coming across.

"systemNotes[6]":"January+09%2C+2013+12%3A52+PM+-+First+Name+-+Changed++Billing+Address+2+From++to+Shipping+First+Name%3A%09+Shipping+Last+Name%3A%09+Email+Address%3A%09+Shipping+Address%3A+%09+Shipping+Address+2%3A+%09+Shipping+City%3A+%09+Shipping+Zip%2FPostal%3A+%09+Shipping+Country%3A+%09+Shipping+State%3A+%09+Phone%3A+%09+Billing+First+Name%3A+%09+Billing+Last+Name%3A+%09+Billing+Address%3A+%09+Billing+Address+2%3A+%09+Billing+C"

This seems to be ok so maybe the problem is coming from when I do the parse_str, here's the code I am using:

$response = apiConnection($data);
parse_str($response, $parse);
$each = json_decode($parse['data']);
foreach($each as $key => $order){
   //do something
}
AD7six
  • 63,116
  • 12
  • 91
  • 123
Scott
  • 187
  • 2
  • 9
  • How are you collecting the string? – aynber Jul 19 '13 at 18:20
  • I am querying an API and it is sending it back to me as a string. Which I am then using a parse_str on which leaves it in an array. – Scott Jul 19 '13 at 18:21
  • 1
    Could you check if the string has non-UTF 8 characters? – Karan Ashar Jul 19 '13 at 18:25
  • If it was a properly constructed json string, the tabs/spaces wouldn't matter. – Marc B Jul 19 '13 at 18:26
  • I have tested it (after adding curly braces) and it seems to have no problem. Are you interested in the occult? – Casimir et Hippolyte Jul 19 '13 at 18:28
  • The issue doesn't paste properly in stackoverflow. It seems to have turned those into plain spaces. I am getting a better example. – Scott Jul 19 '13 at 18:30
  • It is hard to debug without walk through the raw JSON string. Since you could not paste actual JSON, just give details about api – HILARUDEEN S ALLAUDEEN Jul 19 '13 at 18:44
  • Agree with @KaranAshar -- you should verify the whole string is UTF-8 encoded, at least to determine if it is the problem. `mb_check_encoding($string, "UTF-8")` – Jacob S Jul 19 '13 at 18:57
  • Hey Karan and Jacob, that statement came back false for UTF-8. – Scott Jul 19 '13 at 19:04
  • 1
    THanks for that link AD7six: http://codepad.org/ZzrC7rqQ – Scott Jul 19 '13 at 19:05
  • I hope that the JSON string has tab instead space. Convert tabs in JSON string into space before doing json_decode(). Probably this link will help you http://stackoverflow.com/questions/1181559/how-do-i-replace-tabs-with-spaces-within-variables-in-php – HILARUDEEN S ALLAUDEEN Jul 19 '13 at 19:24
  • 1
    Out of curiosity, how is the passed string generated? Is it under your control? – Ja͢ck Jul 24 '13 at 23:52
  • Because it is unclear: What is the response string? I guess that you meant the problem comes with json_decode and not parse_str. – Jim Martens Jul 26 '13 at 18:44
  • This question is Unclear because we don't have a [mcve]. We have the input, but what is your desired output from that input? – mickmackusa Jan 17 '21 at 06:40

2 Answers2

11

The problem is that tab characters are not valid inside a string.

Removing the tab characters like here http://codepad.org/8fnQphkS and using that at jsonlint.com you will see it see now valid json.

Have a look at the specs for JSON at http://www.ietf.org/rfc/rfc4627.txt?number=4627 specially section 2.5 where the tab character is called out by name as one of the characters that must be escaped if inside a string.

EDIT:

Here is a way of stripping out all tabs and multiple spaces and replacing them with a single space character:

$data = preg_replace('/[ ]{2,}|[\t]/', ' ', trim($data));
CodeReaper
  • 5,988
  • 3
  • 35
  • 56
  • He would be better off decoding the json *before* he removes the url encoding, though. – Sam Dufel Jul 25 '13 at 00:11
  • 1
    `$data = preg_replace('/[\s]+|[\t]/', ' ', trim($data));` - all types of whitespace – AKi Jun 05 '15 at 13:38
  • If you are going to proceed with mutating the full string, then just replace one or more whitespace characters with a single literal space. `'/\s+/', ' '` – mickmackusa Jan 17 '21 at 06:20
6

did you try something like that? it would help to clean your string

$yourstring = preg_replace('/[^(\x20-\x7F)]*/','', $yourstring);
Pascamel
  • 953
  • 6
  • 18
  • 28