178

I have this JSON object stored on a plain text file:

{
    "MySQL": {
        "Server": "(server)",
        "Username": "(user)",
        "Password": "(pwd)",
        "DatabaseName": "(dbname)"
    },
    "Ftp": {
        "Server": "(server)",
        "Username": "(user)",
        "Password": "(pwd)",
        "RootFolder": "(rf)"
    },
    "BasePath": "../../bin/",
    "NotesAppPath": "notas",
    "SearchAppPath": "buscar",
    "BaseUrl": "http:\/\/montemaiztusitio.com.ar",
    "InitialExtensions": [
        "nem.mysqlhandler",
        "nem.string",
        "nem.colour",
        "nem.filesystem",
        "nem.rss",
        "nem.date",
        "nem.template",
        "nem.media",
        "nem.measuring",
        "nem.weather",
        "nem.currency"
    ],
    "MediaPath": "media",
    "MediaGalleriesTable": "journal_media_galleries",
    "MediaTable": "journal_media",
    "Journal": {
        "AllowedAdFileFormats": [
            "flv:1",
            "jpg:2",
            "gif:3",
            "png:4",
            "swf:5"
        ],
        "AdColumnId": "3",
        "RSSLinkFormat": "%DOMAIN%\/notas\/%YEAR%-%MONTH%-%DAY%\/%TITLE%/",
        "FrontendLayout": "Flat",
        "AdPath": "ad",
        "SiteTitle": "Monte Maíz: Tu Sitio",
        "GlobalSiteDescription": "Periódico local de Monte Maíz.",
        "MoreInfoAt": "Más información aquí, en el Periódico local de Monte Maíz.",
        "TemplatePath": "templates",
        "WeatherSource": "accuweather:SAM|AR|AR005|MONTE MAIZ",
        "WeatherMeasureType": "1",
        "CurrencySource": "cotizacion-monedas:Dolar|Euro|Real",
        "TimesSingular": "vez",
        "TimesPlural": "veces"
    }
}

When I try to decode it with json_decode(), it returns NULL. Why? The file is readable (I tried echoing file_get_contents() and it worked ok).

I've tested JSON against http://jsonlint.com/ and it's perfectly valid.

What's wrong here?

6
  • 8
    Working with PHP 5.2.9; thus, I can't use json_last_error(). Commented Mar 9, 2010 at 15:57
  • 1
    Also note this can happen with other invalid characters in the middle of the file. I just had json_decode() returning null because the string contained one of those special en-dashes, probably pasted from MS Word, and then maybe mis-encoded. To identify potential problem characters, open the JSON file (I used in Notepad++), change the encoding (without converting), and save as a copy. Then diff the two files (I used WinMerge). Commented Jan 17, 2012 at 17:15
  • (Windows Notepad issue) Please, consult this, I shared the problem too and it fixed it: stackoverflow.com/questions/10290849/… Commented Sep 19, 2014 at 14:49
  • possible duplicate of json_decode returns NULL after webservice call Commented Dec 3, 2014 at 18:17
  • For me, it wasn't anything special, just an extra comma in the end of an object's element. Take away : Anything which makes your JSON inconsistent, is going to throw an error. Bonus tip: don't trust jsonviewer.stack.hu Use something like jsonlint Commented Oct 24, 2016 at 11:30

25 Answers 25

139

Community warning: This approach is not correct. The code below likely tries to remove the BOM sequence (which is why it "works" for some) but it can do irreparable collateral damage to JSON contents as well, removing or breaking valid multi-byte characters.
Instead of corrupting your data, consider checking the actual error message as suggested in this and this answer. Also consider checking JSON visually, especially any characters outside of JSON string - they are not allowed. There can be BOM, spaces, or some HTML added by misconfigured web-server or transport. All this must be removed before decoding.

This worked for me

json_decode( preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $json_string), true );
Sign up to request clarification or add additional context in comments.

6 Comments

I have used this and got the array but my language specific characters (ş,ç,ö,..) has been deleted too.
This is not correct if the json data is UTF-8 encoded (or any UTF encoding I guess). It will remove valid UTF-8-encoded data. It will probably work as long as the file only contains english language, but that's always a risky assumption. I wouldn't use this.
With this it works but without it doesn't, even tho the two string are identical, am I missing something?
it does work! but why? the string I tried to decode did not have any special chars in it
this removes farsi / arabic characters too. I want them to be included into the json. Any Ideas?
|
101

It could be the encoding of the special characters. You could ask json_last_error() to get definite information.

11 Comments

I've been using the special characters since I started the application and there were no problems before. Locally, the JSON decoding works perfectly. On my server, it doesn't. And I can't call json_last_error() because it's PHP 5.2.9. That function appears on PHP 5.3.0.
Nah, this should work. I can't do more testing right now, if I get to it later I'll post here. There are also a few hints in the user contributed notes: de.php.net/json_decode maybe something helps.
For me, on PHP 5.3, it works fine when the text is encoded in UTF-8. But if I pass the text through utf8_decode() first, then json_decode() silently fails.
@Pekka Looking for answers on Google, I got back to SO: stackoverflow.com/questions/689185/json-decode-returns-null-php. My JSON file had the UTF BOM sequence (some binary chars that shouldn't be there), thus, breaking the JSON structure. Went to Hex Editor, erased the bytes. Everything's back to normal. Why has this happened? Because I edited the file using Micro$oft Windows' Notepad. Terrible idea!
This should be reported as a bug to the PHP folks. If the BOM was valid UTF8, it should not choke on it silently.
|
62

You could try with it.

json_decode(stripslashes($_POST['data']))

1 Comment

This has worked for me, I was passing JSON string with ajax to PHP
25

If you check the the request in chrome you will see that the JSON is text, so there has been blank code added to the JSON.

You can clear it by using

$k=preg_replace('/\s+/', '',$k);

Then you can use:

json_decode($k)

print_r will then show the array.

2 Comments

Did it for me!! A simple tweak I made is adding a space in the replace, am using this, and it seems to replace my space as well. works fine now. $k=preg_replace('/\s+/', ' ',$k);
The problem is, this removes every single space, making english text all stuck together isn't it ?
25

Maybe some hidden characters are messing with your json, try this:

$json = utf8_encode($yourString);
$data = json_decode($json);

Comments

17

I had the same problem and I solved it simply by replacing the quote character before decode.

$json = str_replace('"', '"', $json);
$object = json_decode($json);

My JSON value was generated by JSON.stringify function.

1 Comment

In this case the function htmlspecialchars has possibly being used and the JSON cannot be parsed anymore. To reverse it there is the function "htmlspecialchars_decode" instead of manually replacing "
10

This error means that your JSON string is not valid JSON!

Enable throwing exceptions when an error happens and PHP will throw an exception with the reason for why it failed.

Use this:

$json = json_decode($string, null, 512, JSON_THROW_ON_ERROR);

Comments

9

For me the php function stripslashes() works when receiving json from javascript. When receiving json from python, the second optional parameter to the json_decode call does the trick since the array is associative. Workes for me like a charm.

$json = stripslashes($json); //add this line if json from javascript
$edit = json_decode($json, true); //adding parameter true if json from python

Comments

6

Just thought I'd add this, as I ran into this issue today. If there is any string padding surrounding your JSON string, json_decode will return NULL.

If you're pulling the JSON from a source other than a PHP variable, it would be wise to "trim" it first:

$jsonData = trim($jsonData);

Comments

6

this help you to understand what is the type of error

<?php
// A valid json string
$json[] = '{"Organization": "PHP Documentation Team"}';

// An invalid json string which will cause an syntax 
// error, in this case we used ' instead of " for quotation
$json[] = "{'Organization': 'PHP Documentation Team'}";


foreach ($json as $string) {
    echo 'Decoding: ' . $string;
    json_decode($string);

    switch (json_last_error()) {
        case JSON_ERROR_NONE:
            echo ' - No errors';
        break;
        case JSON_ERROR_DEPTH:
            echo ' - Maximum stack depth exceeded';
        break;
        case JSON_ERROR_STATE_MISMATCH:
            echo ' - Underflow or the modes mismatch';
        break;
        case JSON_ERROR_CTRL_CHAR:
            echo ' - Unexpected control character found';
        break;
        case JSON_ERROR_SYNTAX:
            echo ' - Syntax error, malformed JSON';
        break;
        case JSON_ERROR_UTF8:
            echo ' - Malformed UTF-8 characters, possibly incorrectly encoded';
        break;
        default:
            echo ' - Unknown error';
        break;
    }

    echo PHP_EOL;
}
?>

1 Comment

Since PHP 5.5.0 you can use the method json_last_error_msg to get a somewhat helpful message
4

It's probably BOM, as others have mentioned. You can try this:

    // BOM (Byte Order Mark) issue, needs removing to decode
    $bom = pack('H*','EFBBBF');
    $response = preg_replace("/^$bom/", '', $response);
    unset($tmp_bom);
    $response = json_decode($response);

This is a known bug with some SDKs, such as Authorize.NET

Comments

3

The most important thing to remember, when you get a NULL result from JSON data that is valid is to use the following command:

json_last_error_msg();

Ie.

var_dump(json_last_error_msg());
string(53) "Control character error, possibly incorrectly encoded"

You then fix that with:

$new_json = preg_replace('/[[:cntrl:]]/', '', $json);

Comments

3

Here is how I solved mine https://stackoverflow.com/questions/17219916/64923728 .. The JSON file has to be in UTF-8 Encoding, mine was in UTF-8 with BOM which was adding a weird &65279; to the json string output causing json_decode() to return null

Comments

3

This happen because you use (') insted {") in your value or key.

Here is wrong format.

{'name':'ichsan'}

Thats will be return NULL if you decode them.

You should pass the json request like this.

{"name":"ichsan"}

Comments

2

If you are getting json from database, put

mysqli_set_charset($con, "utf8");

after defining connection link $con

1 Comment

Thank-you TomoMiha. This is exactly what fits all my problems with MySQL containing special characters and when converted by json_decode, that particular field was yielded = null....
2

So, html_entity_decode() worked for me. Please try this.

$input = file_get_contents("php://input");
$input = html_entity_decode($input);
$event_json = json_decode($input,true);

Comments

2

It took me like an hour to figure it out, but trailing commas (which work in JavaScript) fail in PHP.
This is what fixed it for me:

str_replace([PHP_EOL, ",}"], ["", "}"], $JSON);

Comments

2
  • I also face the same issue...
  • I fix the following steps... 1) I print that variable in browser 2) Validate that variable data by freeformatter 3) copy/refer that data in further processing
  • after that, I didn't get any issue.

Comments

1

I recommend creating a .json file (ex: config.json). Then paste all of your json object and format it. And thus you will be able to remove all of that things that is breaking your json-object, and get clean copy-paste json-object.

Comments

1

In my case , i was facing the same issue , but it was caused by slashes inside the json string so using

json_decode(stripslashes($YourJsonString))

OR

json_decode( preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $YourJsonString), true );

If the above doesnt work, first replace the quotes from html quote , this might be happening if you are sending data from javascript to php

    $YourJsonString = stripslashes($YourJsonString);
    $YourJsonString = str_replace('&quot;', '"', $YourJsonString);
    $YourJsonString = str_replace('["', '[', $YourJsonString);
    $YourJsonString = str_replace('"]', ']', $YourJsonString);
    $YourJsonString = str_replace('"{', '{', $YourJsonString);
    $YourJsonString = str_replace('}"', '}', $YourJsonString);
    $YourJsonObject = json_decode($YourJsonString);

Will solve it,

Comments

1

Before applying PHP related solutions, validate your JSON format. Maybe that is the problem. Try this online JSON format validator.

Comments

0

Just save some one time. I spent 3 hours to find out that it was just html encoding problem. Try this

if(get_magic_quotes_gpc()){
   $param = stripslashes($row['your column name']);
}else{
  $param = $row['your column name'];
}

$param = json_decode(html_entity_decode($param),true);
$json_errors = array(
JSON_ERROR_NONE => 'No error has occurred',
JSON_ERROR_DEPTH => 'The maximum stack depth has been exceeded',
JSON_ERROR_CTRL_CHAR => 'Control character error, possibly incorrectly encoded',
JSON_ERROR_SYNTAX => 'Syntax error',
);
echo 'Last error : ', $json_errors[json_last_error()], PHP_EOL, PHP_EOL;
print_r($param);

Comments

0

I've solved this issue by printing the JSON, and then checking the page source (CTRL/CMD + U):

print_r(file_get_contents($url));

Turned out there was a trailing <pre> tag.

Comments

0

you should ensure these points

1. your json string dont have any unknowns characters

2. json string can view from online json viewer (you can search on google as online viewer or parser for json) it should view without any error

3. your string dont have html entities it should be plain text/string

for explanation of point 3

$html_product_sizes_json=htmlentities($html);
    $ProductSizesArr = json_decode($html_product_sizes_json,true);

to (remove htmlentities() function )

$html_product_sizes_json=$html;
    $ProductSizesArr = json_decode($html_product_sizes_json,true);

Comments

0

For my case, it's because of the single quote in JSON string.

JSON format only accepts double-quotes for keys and string values.

Example:

$jsonString = '{\'hello\': \'PHP\'}'; // valid value should be '{"hello": "PHP"}'
$json = json_decode($jsonString);
print $json; // null

I got this confused because of Javascript syntax. In Javascript, of course, we can do like this:

let json = {
    hello: 'PHP' // no quote for key, single quote for string value
}

// OR:
json = {
    'hello': 'PHP' // single quote for key and value
}

but later when convert those objects to JSON string:

JSON.stringify(json); // "{"hello":"PHP"}"

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.