PHP - Unable to send JSON correctly - javascript

I'm not sure why this isn't working, as a lot of the examples on the internet suggest doing it this way. Anyway, I have a SQL result that I've converted to JSON and now I'm trying to use that with Javascript.
json_encode($test, true); ?>
<script type="text/javascript">
var obj = (<?php echo $test; ?>);
alert(obj.toSource());
</script>
This does not work and Chrome gives me an error of "illegal character" and the Javascript variable somehow displays some x-debug HTML from the PHP server:
If I simple echo the JSON out to display on the webpage that works fine without any errors. What am I doing wrong?

Do it like this:
$test = json_encode($test, true);
json_encode doesn't change the variable in place.

You're doing a couple of things wrong here..
json_encode($test, true);
I think you're probably thinking of json_decode, but the second parameter to json_encode is supposed to be a bitmask of options. Passing true here is probably wrong.
#ElmoVanKielmo is also correct, the variable doesn't change because you call a function, you must reassign the variable to the return value.

You got hmtl that looks line an xdebug error/notice message. Fix that before you proceed! (You cut out the part where the message is put).
Additionally you do not encode $test correctly. json_encode returns the changed value and does not modify it by reference.

Related

Is it safe to do this? PHP's json_encode and javascript

I've been searching around for security concerns about using PHP json_encode inside javascript context but I'm not exactly satisfied with the results
I got a lot of warnings about doing this but they always assume that I was going to inject data from the json_encode object directly to HTML without any type of sanitizing at all
So, I want to know if this and only this little snippet presents any security issues (like xss attacks etc)
<?php
$obj = isset($_POST['js']) ? json_encode($_POST['js']) : false;
if ($obj === false) $obj = '{}';
?>
<script>var x = <?php echo $obj ?>;</script>
EDIT:
Changed the snippet to handle json_encode returning false
With that line of code
var x = <?php echo $obj ?>;
...the server application echoes back the data that was submitted to it via the "js" key. It will be client that sent it that will receive it, so if in some way it is malicious, it will be that same client dealing with the consequences.
The actual sending to the server is in fact the irrelevant part of the chain: if one has the data to submit, one can also assign it to the variable x directly without the server's interference (e.g. through browser's dev tools).
It would be a different story if in PHP you would use the data to manipulate a server database, call a service, or otherwise change the application's state, and you would not first validate that data.
As to the use of json_encode: if indeed you verify that the argument is valid JSON (by checking that the return value is not false), it will produce a valid JavaScript object literal. The known cases of incompatibility (characters U+2028 and U+2029) will not occur, as by default json_encode escapes these characters.
It is correct as per coding. However you have to validate the variable x should not be empty or the posted value.
<script>var x = "<?php if(isset($_POST['js']))
{
echo json_encode($_POST["js"]);
}";
</script>
Sometimes json_encode returns false, if return it that js expression will broke. this will works safer.
<script>var x = JSON.parse(<?php echo (json_encode($_POST["js"]) ? json_encode($_POST["js"]) : '{}'));</script>
if json_encode returns false, var x will get just empty object.

PHP converting JSON string into Object or Array

I know if I search this on google you get lots of hits back, and i have spent the last 2 days trying to figure out whats happening, and been unsuccessful.
So, I am using Wordpress, but not sure that has any relevance to my issue, and I have a valid JSON string in storage and I need it to be put in PHP and then an object.
The JSON string was an object in PHP which i converted because i needed it in sessionStorage, so here is how i converted it in PHP:
$encodedTime = json_encode($time);
$encodedTime = str_replace("'", "", $encodedTime);
This is then loaded into a element:
<a class="button" href="/?page_id=714" name="viewButton" rel='<?php echo $encodedTime ?>'>View</a>
Here is the object now stored into sessionStorage on the browser:
{"uuid":"108-417f-b5e6-970baec37","low":2929,"run":50793,"contact":"a07-e4b0-4977-ad10-af7aecf4ef80","completed":true,"values":[{"category":{"base":"Great","eng":"Great"},"node":"f85ed85-495e-8eaf-1e6cfdbadf97","time":"2015-10-12T11:28:13.371Z","text":"Great thanks","rule_value":"Great","value":"Great","label":"Response 1"}],"steps":[{"node":"83e332e0-a456-449f-a4f6-cee688f9395b","arrived_on":"2015-10-12T11:27:43.866Z","left_on":"2015-10-12T11:27:44.052Z","text":"Hello! Good Morning This morning?","type":"A","value":"None"},{"node":"f85ed8a8-e745-495e-8eaf-1e6cfdbadf97","arrived_on":"2015-10-12T11:27:44.052Z","left_on":"2015-10-12T11:28:13.371Z","text":"Great thanks","type":"R","value":"Great"},{"node":"424912da-e680-432d-877c-307117366f98","arrived_on":"2015-10-12T11:28:13.374Z","left_on":"2015-10-12T11:28:13.477Z","text":"Thats great to hear!, Wishing you a good day","type":"A","value":"None"}],"created_on":"2015-10-12T11:27:43.721Z","modified_on":"2015-10-12T11:28:13.482Z","expires_on":null,"expired_on":null,"runtime":"12 - 10 # 11 hour"}
This has been validated with JSONLint.
Here is the PHP code:
$time = "<script>document.write(time)</script>";
If i now print_r($time) I get the same printed, a valid JSON string. Great!
Based on what i have read PHP has json_decode for such a requirement, but it does not work, but it does give me a blank space
$time = json_decode("<script>document.write(time)</script>", true); // PHP Code
print_r($time);
If I try and json_encode it gives me funny characters.
If I try and make it an object using :
$time = (object) json_decode("<script>document.write(time)</script>", true);
It gives me :
stdClass Object ( )
$time = (object) "document.write(time)";
stdClass Object ( [scalar] => {"uuid":"1788-417f-b5e6-970bab44ec37","low":2629,"run":5046793,"contact":"a0eb0-4977-ad10-af7aecf4ef80","completed":true,"values":[{"category":{"base":"Great","eng":"Great"},"node":"f85ed85-495e-8eaf-1e6cfdbadf97","time":"2015-10-12T11:28:13.371Z","text":"Great thanks","rule_value":"Great","value":"Great","label":"Response 1"}],"steps":[{"node":"83e332e0-a45-a4f6-cee688f9395b","arrived_on":"2015-10-12T11:27:43.866Z","left_on":"2015-10-12T11:27:44.052Z","text":"Hello! morning?","type":"A","value":"None"},{"node":"f85ed8a8-5e-8eaf-1e6cfdbadf97","arrived_on":"2015-10-12T11:27:44.052Z","left_on":"2015-10-12T11:28:13.371Z","text":"Great thanks","type":"R","value":"Great"},{"node":"424912da-e680-432d-877c-307117366f98","arrived_on":"2015-10-12T11:28:13.374Z","left_on":"2015-10-12T11:28:13.477Z","text":"Thats great to hear!, Wishing you a good day","type":"A","value":"None"}],"created_on":"2015-10-12T11:27:43.721Z","modified_on":"2015-10-12T11:28:13.482Z","expires_on":null,"expired_on":null,"runtime":"12 - 10 # 11 hour"} )
So I am at a loss, as to why it will not work. I have the option to use Javascript and use the information, but I really need it in PHP as there is more working to be done with this information.
Could someone please help point me where, and why, it's going wrong ?
You can't get a javascript variable value using PHP code. They're differente things. If you want to understand more, i recommend you read this question.
So... How to do it?
If you wanna use that data in the back-end, you need to create a AJAX request, as RambRaider said. If you need this in the front-end, you can simply parse the json data using JSON.parse.

How to obfuscate JavaScript on the server side?

I have a script I want to obfuscate or encrypt to hide from competition viewing the source code. I have found simple JS obfuscators but the issue with my script is I have PHP echoing variables into the JavaScript. The PHP is echoing strings and true/false.
Here is a piece of the JavaScript with PHP in it.
function redirect() {
var r = <?php echo $rvar; ?>;
if (r) {
window.location = prepare("<?php echo $redirect; ?>");
}
}
Can someone tell me what I can do to hide my JavaScript but be able to dynamically build the JS with PHP?
The only time I have ever wanted to obfuscate code is when I have been utterly ashamed of it. Retrospectively, I would probably obfuscate everything I have ever written. If protecting source is integral to your well-being, consider a shift to desktop programming.
Nevertheless, if there is one thing experience and memory has afforded me, it is that any serious newcomer to this field will stubbornly move forward with their own ideas, regardless of how bad it is, how much it grinds against commonsense and best practice, or how much a thread poo-poos all over the question. If you keep at it, hindsight will generously remind you of this period--cringes and all; the chastisements of a few strangers will pale in comparison, so I will give you one possible answer.
Use PHP's output buffering controls. You will want to start output buffering at the top of the script that will output all the JavaScript. This will capture everything into the buffer, which can then be assigned to a simple variable. This variable will contain everything that was supposed to be echoed out to the page immediately, but was instead captured and saved into the variable. This variable is just a regular string. Pass it to one of those JS obfuscators you found. This assumes it is done with PHP and is a PHP library for doing that. When it is obfuscated, echo it out. That is it. Here is an example:
<?php
// Start output buffering.
ob_start();
?>
function redirect() {
var r = <?php echo $rvar; ?>;
if (r) {
window.location = prepare("<?php echo $redirect; ?>");
}
}
<?php
// Get all the output captured in the buffer, and turn off output buffering.
// This will be a string.
$js_source = ob_get_flush();
// Obfuscate the $js_source string, by passing it to the obfuscator
// library you found.
$obfuscated_js_source = obfuscator5000($js_source);
// Send the source code to the browser by echoing it out.
echo $obfuscated_js_source;

Passing JSON directly to Javascript without JSON.parse()

I noticed that many people are passing objects from PHP to Javascript as JSON like this:
var obj=JSON.parse('<?php echo json_encode($obj) ?>');
or
var obj=jQuery.parseJSON('<?php echo json_encode($obj) ?>');
Why don't people pass JSON directly like this?
var obj=<?php echo json_encode($obj) ?>;
This works fine with the few objects that I tried. Are there cases when this won't work?
passing objects from PHP to Javascript as JSON like this:
var obj=JSON.parse('<?php echo json_encode($obj) ?>');
Ouch! You're right, this is overcomplicated. Also, it actually has serious problems with apostrophes and backslashes in the JSON string, which are not escaped and destroy the string literal.
Why don't people pass JSON directly?
People who do it properly do it this way indeed.
Are there cases when this won't work?
Yes. There are unicode characters that are valid in pure JSON, but a syntax error in JavaScript - see http://timelessrepo.com/json-isnt-a-javascript-subset for details. However, json_encode would output these as escape sequences anyway.
Generally, you'd use JSON parsers to secure situations where the code returned may be erroneous (instead of crashing your script, it will simply throw an exception and keep going). This is generally a good idea when the JSON is sent from a source you don't have control over. It seems unnecessary when you're in control of both ends (PHP server and JS client).
That said, a "safer" method just for server side would be:
<?php $json_encoded = json_encode ($obj); ?>
var obj=<?php echo ($json_encoded ? $json_encoded : 'null'); ?>;
This makes sure only a valid object is passed into JavaScript.
More info: https://api.jquery.com/jQuery.parseJSON/

How do I pass HTML tags through getJSON?

I'm trying to pass a json_encode-d array from PHP to JavaScript using JQuery's getJSON, and then display it in the HTML. It works fine in all cases except when I want to pass basic HTML tags, e.g. 34 shows up as:
3<sup>4</sup>
It works fine when I have:
var myVar = <?php echo json_encode(jsonArray); ?>;
But I need to use getJSON as well. Is there a simple way to do this? Maybe a regex I failed to figure out?
Try this:
$('#YourTarget').html( $('<div/>').html(yourStringFromJSON).text());
For example:
$('h1').html( $('<div/>').html('Hola<sup>Hey</sup>').text());
Here's the regex to unescape the forward slash:
var cleanString = dirtyString.replace(/\\\//g,"/");

Categories

Resources