16

I am facing some issue with json_encode.

when i json_encode an array having new lines it is not escaping new lines instead it's removing \ and keeping n.

ex: $array = array('name'=> "some text \n\r text");
$results = json_encode($array);

it is saving some text nr text in database .

i am using php 5.3.8.

edit:

This is my original code i am using

$attr = array();
for($i=0; $i < count($_POST['key']); $i++){
    $attr[$_POST['key'][$i]] = $_POST['value'][$i];
}
echo json_encode(array('custom' => $attr));

these POST values getting from form.

10
  • Are you sure it's json_encode that's causing the problem? What do you get if you print_r($results); out in a browser? Ah and it should be \r\n... Commented Jun 29, 2012 at 15:31
  • Cannot reproduce. Are you sure you're looking at the raw output? Commented Jun 29, 2012 at 15:32
  • 1
    1) shouldn't it be \r\n, 2) how do you send that string to your database? did you properly quote / escape the value (or at the very least use addslashes()) on it? Commented Jun 29, 2012 at 15:32
  • working fine with me, same PHP version. Any other operations you're doing before inserting in the databse? Commented Jun 29, 2012 at 15:33
  • thanks, when i do print_r($array) ouput is fine with new line, after json_encode() if i do json_decode() output is coming like above with out newlines.. Commented Jun 29, 2012 at 15:34

8 Answers 8

10

I don't believe json_encode is your problem. My guess is your database is interpreting \ as the escape character, so it simply strips them out.

To combat that, simply escape the escape characters using addslashes:

$results=addslashes($results);
Sign up to request clarification or add additional context in comments.

3 Comments

This solution works : order = JSON.parse( '<?php echo addslashes( json_encode( $order ))?>' );
I gave you an upvote for this as real_escape_string fixed my problem
I searched a lot and this one was the best :) Thank you :)
10

Newlines are not valid characters inside of JSON strings. That's the expected behavior:

char

any Unicode character except " or \ or control-character

  • \"
  • \
  • /
  • \b
  • \f
  • \n
  • \r
  • \t
  • \u four-hex-digits

JSON escapes those control characters into those in the list.

So now we have '\n' (literally a backslash followed by 'n'), which, if not escaped properly, will be saved in the database as n. And that is the problem you're experiencing.

The Solution

Use prepared statements to properly escape any and all slashes in the strings you're storing in your database. That will save them as '\n', which you can convert to "\n" when you retrieve your data.

8 Comments

Any suggestion for what he can do instead?
@andrewtweber: Use prepared statements properly?
Yes, but that would still escape the literal "\n" character to the escaped sequence '\n'... which my guess would mean there is something that is being done wrong on it's way to the database meaning not "a problem with json_encode". It is also just possible that the database viewer logicsinc is using doesn't support displaying \n properly ;)
@pebbl: No, as I said, that's the expected behavior. JSON doesn't support newlines, so it converts it into '/n'. If he uses prepared statements, that sequence will be saved, and it can be restored to "/n" once retrieved.
@Truth ah ok I missed the part where it converted it to /n, I thought it just removed the `\`
|
3

You could manually escape them:

$array = array('name'=> "some text \n\r text");

$results = json_encode(array_filter($array, function($arr) use ($array){
        return preg_replace('~\\[nrtfd]~', '\\\\$1', $arr);
}));

print_r($results);

You could extend your own json_encode function, and replace your uses of json_encode to my_json_encode:

function my_json_encode($json){
    $results = json_encode(array_filter($json, function($arr) use ($array){
        return preg_replace('~\\[nrtfd]~', '\\\\$1', $arr);
    }));

    return $results;
}

print_r($results);

FYI, the above returns: {"name":"some text \n\r text"} instead of {"name":"some text nr text"}

1 Comment

i can't do that manually.. i am using json_encode number places.
3

You could use JSON_PRETTY_PRINT as described in the PHP manual.

https://www.php.net/manual/function.json-encode.php

Comments

0

I figured out this issue. it is not in json_encode problem. it is an error while saving to database.

The problem is magic_quotes_gpc enabled in server. in my application if magic_quotes enabled i am striping the slashes.

i disabled magic_quotes_gpc. working fine now.

Thanks for every body.

1 Comment

how did you disable it ?
0

You could use PHP_EOL for a new line. Where to include new line depends on how you want. In the case below, i need a new line after the last closing square bracket and each curly bracket:

tit1: {
"prop1" : [ "", "", []], 
"prop2" : [ "", "", []]
}, 
tit2: {
"prop1" : [ "", "", []], 
"prop2" : [ "", "", []]
}

The function is

$jsonDataTxt = $this->own_format_json($jsonData);
file_put_contents("C:/Users/mm/Documents/Data.json", $jsonDataTxt);


function own_format_json($json, $html = false) {
        $tabcount = 0; 
        $result = ''; 
        $bnew = 0;
        $brack=0;  
        $tab = "\t"; 
        $newline = PHP_EOL; 
        for($i = 0; $i < strlen($json); $i++) { 
            $char = $json[$i]; 
            if($char!==',' && $bnew===1) { $bnew=0; $result.=  $newline; } //insert new line after ], which is not proceeded by ,
            switch($char) { 
                case '{': 
                    $tabcount++; 
                    $result .= $char . $newline . str_repeat($tab, $tabcount); 
                    break; 
                case '}': 
                    $tabcount--; 
                    $result = trim($result) . $newline . str_repeat($tab, $tabcount) . $char . $newline; 
                    break; 
                case '[': 
                    $brack++; 
                    $result .= $char;// . $newline . str_repeat($tab, $tabcount); 
                    break; 
                case ']': 
                    $brack--;
                    $result .= $char;// . $newline . str_repeat($tab, $tabcount); 
                    if($brack===0) { $bnew=1; }
                    //echo "<br><br> case  ]  char=".$char.',   brack='.$brack. ",  bnew=".$bnew.",   result=".$result ; 
                    break; 
                case ',': 
                    $result .= $char;// . $newline . str_repeat($tab, $tabcount); 
                    if($bnew===1) { $bnew=0; $result.=  $newline; } //insert new line after ],
                    break; 
                case '"': 
                    $result .= $char; 
                    break; 
                default: 
                    $result .= $char; 
            } 
        } 
    return $result; 
   }

Comments

0

I use this command to clean the backslashes.

$info = file_get_contents('my_file.txt');
**$info = str_replace(array("r\n","\n", "\r"), "", $info);**    
$info = json_decode($info);

Comments

0

I've found that the simplest solution is to use JSON_UNESCAPED_UNICODE (along with other flags, if you need them). You can learn more about these flags in the documentation

Regarding the original issue:

<?php
$tmp = array();

$tmp[1] = "test";
$tmp["ok"] = "this
seems to be
a
multiline
nightmare,
but
we
can manage it";

$conv = json_encode($tmp,JSON_UNESCAPED_UNICODE);
echo $conv;
?>

which outputs

{"1":"test","ok":"this\r\nseems to be\r\na\r\nmultiline\r\nnightmare,\r\nbut\r\nwe\r\ncan manage it"}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.