Link to home
Start Free TrialLog in
Avatar of dale_abrams
dale_abrams

asked on

PHP Objects Being Output as Strings

I have an object that is stored in MySQL (varchar) like so
[ {"a \"quoted string\"": "bar"}, {"options":{"foo":"bar"} } ]

Open in new window


I need to output this into a JSON file download like this
[ {"a \"quoted string\"": "bar"}, {"options":{"foo":"bar"} } ]

Open in new window


Right now, its outputting as a string like so
"[ {\"a \"quoted string\"\": \"bar\"}, {\"options\":{\"foo\":\"bar\"} } ]"

Open in new window


I'm using json_encode for the file output and suspecting that that is adding the slashes to the quotes, but not sure why the whole thing is being output as a string as well. So the question is, how can I get it to output without the surrounding quotes, and without the escaping slashes, knowing that I have to use json_encode upon file output?
Avatar of Ray Paseur
Ray Paseur
Flag of United States of America image

JSON requires the double quotes to be escaped with backward slashes.  It's part of the standard.
http://json.org/

That said, if you can post the original data (before the first encoding) I'll be glad to show you the process I use.
And maybe this (from another E-E question) will help.

Link: http://iconoun.com/demo/temp_slick812_client.php

Client side script:
<?php // demo/temp_slick812_client.php

/**
 * See http://www.experts-exchange.com/Programming/Languages/Scripting/PHP/Q_28630465.html
 */
error_reporting(E_ALL);
ini_set('display_errors', TRUE);

// CREATE OUR WEB PAGE IN HTML5 FORMAT
$htm = <<<HTML5
<!DOCTYPE html>
<html dir="ltr" lang="en-US">
<head>
<meta charset="utf-8" />
<meta name="robots" content="noindex, nofollow" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<style type="text/css">
/* STYLE SHEET HERE */
</style>

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
$(document).ready(function(){
    $("#signal").click(function(){
        $.get("temp_slick812_server.php", function(response){
            var obj = $.parseJSON(response);
            var txt = 'Fail';
            if (obj.on)
            {
                txt = obj.name + '<br>' + obj.address + '<br>' + obj.price + '<br>' + obj.quote;
            } else
            {
                alert('Failure');
            }
            $("#output p#target").html(txt);
        });
    });
});
</script>

<title>HTML5 Page With jQuery and JSON in UTF-8 Encoding</title>
</head>
<body>

<noscript>Your browsing experience will be much better with JavaScript enabled!</noscript>

<div   id="signal">Click Here to Retrieve JSON from the Server!</div>
<div   id="output">
   <p  id="target">This element gets the AJAX (JSON) response</p>
</div>


</body>
</html>
HTML5;

// RENDER THE WEB PAGE
echo $htm;

Open in new window

Server-side script:
<?php // demo/temp_slick812_server.php

/**
 * See http://www.experts-exchange.com/Programming/Languages/Scripting/PHP/Q_28630465.html
 * Ref http://php.net/manual/en/function.json-encode.php
 * Ref http://json.org/
 *
 * Return a JSON object that contains both quotes and an apostrophe
 */
error_reporting(E_ALL);
ini_set('display_errors', TRUE);

$data = array
( 'on' => true
, 'name' => "Joker's Krazy"
, 'address' => "123 Ain't St."
, 'price' => 3.50
, 'quote' => 'Tang said "Take the Money!"'
)
;
$json = json_encode($data);
if ( json_last_error() ) echo json_last_error();
echo $json;

Open in new window

Avatar of dale_abrams
dale_abrams

ASKER

Hi Ray,
Unfortunately, the data I am dealing with is sensitive and cannot be shared, but a similar simplified example is like the code below. This is text that is being entered into an html input field and shipped off to PHP via jQuery AJAX.
[ {"foo": "a \"quoted\" string"}, {"options":{"foo":"bar"} } ]

Open in new window


I then need to save it in MySQL, present the info back to the user in the text field, and later output it as part of a JSON file.

I have used htmlentities with the ENT_QUOTES arg to save it into the DB, and that is pulling it out and displaying it in the text field properly, but the problem arises when I go to dump the data into the JSON file. I cannot get it to output like an object (without quotes around it) and without adding extra quote escaping.
The PHP object that is created from that JSON string looks like this:
array(2) {
  [0]=>
  object(stdClass)#1 (1) {
    ["foo"]=>
    string(17) "a "quoted" string"
  }
  [1]=>
  object(stdClass)#2 (1) {
    ["options"]=>
    object(stdClass)#3 (1) {
      ["foo"]=>
      string(3) "bar"
    }
  }
}

Open in new window

Generally speaking, the less you do to a data item, the better.  If your application really requires htmlentities() for something else, such as browser output, it might make sense to use that, but I would not use it on data intended for storage in the database.  Just take the raw, unmodified string and escape it with the appropriate real_escape_string() function, or use it in a prepared query if you're using PDO.  Then store it.  That's all there is to the data base storage side of things.

When you retrieve it from the database, it should look exactly, character-for-character like what you have put into the data base -- no escape sequences, no entities, just the raw JSON data.  It should go without saying, but I'll say it anyway... JSON data is all UTF-8.  Make sure that your character encoding is consistent throughout - HTML, PHP, SQL - all of them have to be UTF-8.  PHP is at an awkward historical moment with respect to UTF-8, but it's possible to get it right anyway.

The backslash before the double quote is a part of the JSON standard.  JavaScript expects this in the JSON string.

This is how I would process it for display:
<?php // /demo/temp_dale_abrams.php

/**
 * SEE http://www.experts-exchange.com/Programming/Languages/Scripting/PHP/Q_28632638.html#a40656868
 */
error_reporting(E_ALL);

$jso = '[ {"foo": "a \"quoted\" string"}, {"options":{"foo":"bar"} } ]';
$raw = json_decode($jso);

// VISUALIZE THE DATA
echo '<pre>';
var_dump($raw);

// SHOW THE COMPONENTS
echo PHP_EOL . $raw[0]->foo;
echo PHP_EOL . $raw[1]->options->foo;

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Ray Paseur
Ray Paseur
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hi Ray,
Thanks so much for taking so much time with this. I have taken your suggestion and gotten the database to store the object exactly as its entered into the text input field. I have it being output back into the input field correctly, but I am still having trouble with exporting it properly.

I failed to mention that I'm using CodeIgniter and do not have access to real_escape_string or mysqli_ real_escape_string.

So what I'm experiencing now is when I echo out the returned data (not through json_encode), it looks correct. When I run it through json_encode it comes out with all slashes escaped and it is quoted as a string like so
"[ {\"foo\": \"a \\"quoted\\" string\"}, {\"options\":{\"foo\":\"bar\"} } ]"

Open in new window


I'm on PHP 5.5.14 and using the JSON_UNESCAPED_SLASHES json_encode arg, but it doesnt seem to be working.
I got the slashes issue fixed with strip slashes. Now just need to get it to stop outputting quotes around the object and I'll be set.
I figured it out. I needed to use json_decode on the object when pulling from the database and then not run strip slashes. Thanks so much for all your help Ray!
Sounds good, glad it's pointed in the right direction now!