JSON decode/encode loses newlines / file structure?
The problem is, it messes up the file format. Before using the script, the file I’m editing looks like this:
< "name": "symfony/framework-standard-edition", "description": "The \"Symfony Standard Edition\" distribution", "autoload": < "psr-0": < "": "src/" >>, "require": < "php": ">=5.3.3", "symfony/symfony": "2.1.*", "doctrine/orm": ">=2.2.3,, "scripts": < "post-install-cmd": [ "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap", "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache", "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets", "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile" ], "post-update-cmd": [ "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap", "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache", "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets", "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile" ] >, "minimum-stability": "dev", "extra": < "symfony-app-dir": "app", "symfony-web-dir": "web" >>
>,"require":=5.3.3","symfony\/symfony":"2.1.*","doctrine\/orm":">=2.2.3,,"scripts":,"minimum-stability":"dev","extra":>
All newlines, etc. are lost. My PHP version is 5.3.10, which means I can’t use PHP 5.4 which has the «PRETTY_PRINT» option for encoding. Is there a way to keep my file structure in PHP 5.3.10 using json_encode();?
Правильный перевод строки в JSON
Как привести к надлежащему виду сам массив в PHP? Для полноты картины прикрепляю скриншот:
Смотрите второй аргумент (параметр) функции json_decode выставите в true и получите массив, а не объект и 3 аргументом укажите глубину рекурсии (в вашем случае 2). И не нужно тулить картинки, давайте более менее рабочие примеры, за вас никто не будет переписывать.
1 ответ 1
В PHP нет такого понятия, которое в JS будет нормально будет интерпретироваться как «Object», stdClass это просто обертка для доступа к полям. И она не удобна для работы, противоестественная для PHP
Совет 1. Используйте json_decode($string, true); , если парсите JSON в PHP — второй параметр true указывает на необходимость представлять JavaScript Object в виде обычных ассоциативных массивов PHP, а не в виде stdClass. С ними на порядок удобнее работать, чем с stdClass, перебор полей, проверки наличия и так далее — все становится очень простым
Совет 2. Не усложняйте себе жизнь колдовством с stdClass в PHP. Используйте обычные ассоциативные массивы. Если ключи массива строковые, он будет преобразован в Object:
$locs = array( "1" => array( "info" => "11111. Some random info here", "lat" => "-37.8139", "lng" => "144.9634" ), "2" => array( "info" => "22222. Some random info here", "lat" => "46.0553", "lng" => "14.5144" ), "3" => array( "info" => "33333. Some random info here", "lat" => "-33.7333", "lng" => "151.0833" ), "4" => array( "info" => "44444. Some random info here", "lat" => "7.9798", "lng" => "-81.731" ) ); print json_encode($locs); /* * JSON-строка: < "1":, "2":, "3":, "4": > */
Удачи! PHP прекрасен своим единственным «массивом» на все случаи жизни, который может все и сразу, а не зоопарком сущностей вроде «кортежей», «хэшей», «словарей» и прочей ереси ))
php json_encode not escaping new lines
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));
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.
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?
working fine with me, same PHP version. Any other operations you’re doing before inserting in the databse?
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..
8 Answers 8
char
- \»
- \
- /
- \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.
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.
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:
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: instead of
You could use JSON_PRETTY_PRINT as described in the PHP manual.
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.
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:
$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 = 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 "
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; >
New lines and tabs in json_decode() (PHP 7)
My code using json_decode() worked correctly with PHP 5.6. After migration to PHP 7.0, json_decode() returns NULL and json_last_error() tells me that my error is:
After debugging, I found out that my problem are both tabs and new line characters in string values. If I remove them both, it works. If I leave either new lines or tabs, the error occurs. Is json_decode() behavior changed in PHP 7? I would like to keep tabs and new lines in my .json files for better readability. The code works if I replace tabs to \t and new lines to \n. How can I keep new lines and tabs?
4 Answers 4
Due to a software licensing issue, the old json module was replaced with the jsond module. You can see the discussion of this change and the attached pull request here. Now, there’s not much information about the changes or about workarounds for things, but I can see that all control characters inside strings ( [\0x00-\0x1F] ) trigger an error. Unfortunately for you, it seems that this behavior is correct per the JSON Standard:
Insignificant whitespace is allowed before or after any token. The whitespace characters are: character tabulation (U+0009), line feed (U+000A), carriage return (U+000D), and space (U+0020). Whitespace is not allowed within any token, except that space is allowed in strings.
So, in other words, literal tabs are not allowed inside JSON strings at all; they must be \t or \u0009 . So, the JSON you’re consuming is in direct violation of the standard. Ideally, you should get your JSON source to return standards-compliant JSON. If that won’t work, you’ll have to pre-process the JSON and convert tabs inside strings to \t .
How to deal with backslashes in json strings php
There appears to be an oddity with json_encode and/or json_decode when attempting decode a string that was produced by json_encode:
$object = new stdClass; $object->namespace = 'myCompany\package\subpackage'; $jsonEncodedString = json_encode($object); echo $jsonEncodedString; // Result of echo being: // $anotherObject = json_decode($jsonEncodedString); echo $anotherObject->namespace; // Result of echo being: // myCompany\package\subpackage $yetAnotherObject = json_decode(''); // Result should be: // myCompany\package\subpackage // But returns an invalid string sequence error instead. echo json_last_error_msg();
I’ve never experienced a problem previous to this, as I’ve never had to capture a string with backslashes in it until today. In reviewing the code above, I can encode/decode utilizing PHP’s built in components. However if I attempt to decode a string that was produced by this encoder I get an error message. I’ve read in documentation items like «Predefined Constants» and other stack questions like «how remove the backslash (“\”) in the json response using php?». But I can’t seem to find a reason WHY I can’t decode a string that was produced by json_encode. The PHP version I’m using to test this code is 5.5.9. I know I could be totally clueless by missing something, but should I be handling my string that was produced by json_encode differently if I attempt to use it elsewhere?
6 Answers 6
The answer is in the question:
$jsonEncodedString = json_encode($object); echo $jsonEncodedString; // Result of echo being: //
You don’t have to strip any slashes. On the contrary. You have to express the echo-ed text as PHP source code.
$yetAnotherObject = json_decode('');
The backslash ( \ ) is a special character in both PHP and JSON. Both languages use it to escape special characters in strings and in order to represent a backslash correctly in strings you have to prepend another backslash to it, both in PHP and JSON.
Let’s try to do the job of the PHP parser on the string above. After the open parenthesis it encounters a string enclosed in single quotes. There are two special characters that needs escaping in single quote strings: the apostrophe ( ‘ ) and the backslash ( \ ). While the apostrophe always needs escaping, the PHP interpreter is forgiving and allows unescaped backslashes as long as they do not create confusion. However, the correct representation of the backslash inside single quoted strings is \\ .
The string passed to function json_decode() is
Please note that this is the exact list of characters processed on runtime and not a string represented in PHP or any other language. The languages have special rules for representing special characters. This is just plain text.
The text above is interpreted by function json_decode() that expects it to be a piece of JSON . JSON is a small language, it has special rules for encoding of special characters in strings. The backslash is one of these characters and when it appears in a string it must be prepended by another backslash. JSON is not forgiving; when it encounters a backslash it always treats it as an escape character for the next character in the string.
The object created by json_decode() after successful parsing of the JSON representation you pass them contains a single property named namespace whose value is:
myCompany\package\subpackage
Note again that this is the actual string of characters and not a representation in any language.
What went wrong?
$yetAnotherObject = json_decode('');
The PHP parser interprets the code above using the PHP rules. It understands that the json_decode() function must be invoked with the text <"namespace":"myCompany\package\subpackage">as argument.
json_decode() uses its rules and tries to interpret the text above as a piece of JSON representation. The quote ( » ) before myCompany tells it that «myCompany\package\subpackage» must be parsed as string. The backslash before package is interpreted as an escape character for p but \p is not a valid escape sequence for strings in JSON. This is why it refuses to continue and returns NULL .