How to improve readability? (pass php vars to javascript in external file) - javascript

I have got the following code:
<HTML>
<?php
if(isset($_GET['adjust'])){
$adjust = true;
}
//More variabele declaring
?>
<HEAD>
<script type="text/javascript">
var adjust = "<?php Print($adjust); ?>";
//More variable 'transports'
</script>
</HEAD>
<!-- rest of the file -->
I would like to clean this up a little, because I have a serious amount of variables. This troubles the readability and overview of the file.
I thought of putting it all into an external JavaScript file, but it didn't seem to work.
<HTML>
<?php
if(isset($_GET['adjust'])){
$adjust = true;
}
//More variabele declaring
?>
<HEAD>
<script type="text/javascript" src="externalJS.js"></script>
</HEAD>
<!-- rest of the file -->
With externalJS.js:
var adjust = "<?php Print($adjust); ?>";
//More variable 'transports'
According to this question, also asked here on stackoverflow, this ain't possible.
Is there a way to do it with the knowledge of the past few years, since above question was answered?
Are there other alternatives to improve the readability?
P.S.: I think it is worth mentioning I gain my php-variables from the url, txt-files and cookies.

When I have had cases where I have had to place a number of variables into javascript, I have used the approach of loading all those items into an object (or array) and outputting that data into an object/array literal in javascript.
For example:
<?php
$js_object = new stdClass();
$js_object->foo = 'some value';
$js_object->bar = 'some other value';
?>
<script type="text/javacript">;
var php_values = <?php echo json_encode($js_object); ?>;
console.log(php_values.foo);
console.log(php_values.bar);
</script>
This does a few things.
Your JS output section does not need to change at all if the variables being passed need to change. Anything you want to access in JS just needs to be loaded in $js_object before the object is output to the browser via json_encode()
It puts all your PHP-provided values in a neat object/array in javascript where they can be accessed.
You can easily pass complex data structures in this manner (nested arrays, objects containing arrays, arrays of objects, etc.)
If needed you could extend the object in javascript to provide methods, etc. to act on the data.
I would also comment that you might want to think a bit about whether you wanted to pass cookie data in this manner. Cookie data is available to javascript anyway so you may want to work with that data directly if you need to change values or such.

Mike Brant's approach is good here (storing everything in a json object), but to accomplish specifically what you are asking here in a more segmented way you can simply make your included javascript library a PHP file that outputs Javascript headers. Your markup would look like this:
<HTML>
<?php
if(isset($_GET['adjust'])){
$adjust = true;
}
//More variabele declaring
?>
<HEAD>
<script type="text/javascript" src="externalJS.js.php?<?=http_build_query($_GET);?>"></script>
</HEAD>
<!-- rest of the file -->
And then your externalJS.js.php file would look like:
<?php
header("content-type: text/javascript");
?>
var adjust = "<?php Print($adjust); ?>";
//More variable 'transports' and any other PHP/Javascript code
The header here tells the browser to treat the result as javascript despite the .php extension.
Also, if you really wanted to you could also just tell you webserver to parse js files as PHP, so that it would look for <?php ... ?> segments and execute them, so you don't even need to have a non-js extension on the file:
AddType application/x-httpd-php .js
But be careful when you do this, as it means that all javascript files (or any files in the specified directory, if you're using htaccess) will be parsed, which could open up security holes if you're not careful.
A couple of side notes:
Have a look at the discussion around text/javascript vs application/javascript
Don't capitalize all the tag names. Yes, HTML5 says it's OK, but the W3C recommends lowercase as a convention (both for standardization and for any possible conversion to xhtml).
When just printing or echoing, first of all use lower-case (print vs Print), don't wrap the printed variable in parentheses (print and echo are language constructs, so they don't need the parentheses and there are situations where using them can cause problems), and lastly, if all you're doing in a PHP tag is printing or echoing, try using PHP echo shorthand (most webservers understand them by default): <?=$var_name;?> is the same as <?php print($var_name);?>

Create an array in PHP containing the variable name (as you want it in javascript) as the key for each element, and the value as you want it in javascript as the value of each element. Then, follow this:
$myVars = array();
$myVars['adjust'] = isset($_POST['adjust']) ? true : false;
$myVars['other'] = isset($_POST['other']) ? true : false;
$myVars['another'] = isset($_POST['another']) ? true : false;
<script type="text/javascript">
<?php
foreach( $myVars as $k => $v ):
echo 'var ' . $k . '="' . $v . '";';
?>
</script>
Cheers

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.

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;

Most efficient way to pass PHP variables to external JavaScript (or jQuery) file

I've read several posts about the question and found this to be the simplest solution, here is my code:
js inside PHP code
<script>
<!--//
var jsBaseurl = <?php echo json_encode(BASE_URL."/"); ?>;
var jsTitle = <?php echo json_encode($h1_title); ?>;
var jsSubtl = <?php echo json_encode($h2_title);?>;
//-->
</script>
<script src="external.js"></script>
and the external.js
var siteURL=jsBaseurl;
alert(siteURL+jsTitle+jsSubtl)
it works fine, my question is regarding to the following comments by Pang and biplav:
WARNING: This can kill your website. Example:
<?php $myVarValue = '<!--<script>'; ?>
See this question for details. Solution: Use
JSON_HEX_TAG to escape < and > (requires PHP 5.3.0). - Pang
Another downside of this is that impacts the inital page load time. -
biplav
I would like to know a simple solution for Pang's comment and how this all impacts the performance (page load time). Thanks a lot!
About question 1: use JSON_HEX_TAG in json_encode()
Example 1
Consider this simple piece of code.
<script>
<?php $myVarValue = 'hello world'; ?>
var myvar = <?php echo json_encode($myVarValue); ?>;
alert(myvar);
</script>
Output:
<script>
var myvar = "hello world";
alert(myvar);
</script>
It alerts hello world. Good.
Example 2
Let's try having </script> as the string.
<script>
<?php $myVarValue = '</script>'; ?>
var myvar = <?php echo json_encode($myVarValue); ?>;
alert(myvar);
</script>
Output:
<script>
var myvar = "<\/script>";
alert(myvar);
</script>
It alerts </script>. Good.
As you can see, the slash (/) is correctly escaped as \/,
Example 3
Now, consider this very special string: <!--<script>
<script>
<?php $myVarValue = '<!--<script>'; ?>
var myvar = <?php echo json_encode($myVarValue); ?>;
alert(myvar);
</script>
Output:
<script>
var myvar = "<!--<script>";
alert(myvar);
</script>
Surprisingly, it does not alert anything, and there's nothing in the error console. What?!
If you check JSON's spec, none of the characters in <!--<script> need to be escaped, so what went wrong?
Image adapted from json.org
For a complete and well explained answer, read this amazing Q & A. In short, it turns out that having
<!--<script> in a <script> block confuses the HTML parser. PHP actually did its job correctly in json_encode();
you just can't have a <!--<script> there, even though it is a perfectly valid JavaScript string!
I did a few simple tests myself. The browsers actually ignore everything after <!--<script>, so if it happens in the middle of a page,
the entire second half of the page is gone! I'm not sure if someone can actually inject something malicious there to, say, execute arbitrary
code, but that's bad enough.
Also,
If you have not just a string in $myVarValue, but a complex object like array("key" => array("one", "and<!--<script>two", 3)), which includes <!--<script>, it's still bad.
If you have a plain HTML file (i.e. no PHP) and you have <!--<script> anywhere (even in a JavaScript comment) in your <script> block, it's also bad.
If you are using other, non-PHP, server-side programming languages, and produced <!--<script>, it's bad too.
If your PHP is outputting JavaScript directly (Content-type: application/javascript), it's actually ok [1].
The solution? Use JSON_HEX_TAG to escape < and > (requires PHP 5.3.0).
<script>
<?php $myVarValue = '<!--<script>'; ?>
var myvar = <?php echo json_encode($myVarValue, JSON_HEX_TAG); ?>;
// ^^^^^^^^^^^^^^
alert(myvar);
</script>
Output:
<script>
var myvar = "\u003C!--\u003Cscript\u003E";
alert(myvar);
</script>
It alerts <!--<script>. Hurray!
It works because there's no more <!--<script> in the output, so no more HTML parsing problems.
Note: you don't need JSON_HEX_TAG if you're not printing into a <script> block.
[1] Here, "ok" merely means it is free from the <!--<script> issue. Dynamically generating external JavaScript files is not recommended as it has tons of disadvantages, such as those stated here, here, here.
About question 2: initial page load time
Actually, it's rather obvious. If the time needed to obtain the value of $myVarValue is long
(e.g. you're fetching lots of data from DB), PHP will have to wait, so is the browser, and the user.
That means longer initial page load time. If you load the data later with Ajax instead, they won't have
to wait to see the initial result, but then, the Ajax call would be an extra HTTP request, so it
means more workload to the server, and more load to the network.
Of course, each method has its pros and cons, so you have to decide. I suggest reading this excellent Q & A.
Pretty sure that won't break it. The whole point of json_encode is that it's safe to dump.
</script> might break it, but PHP escapes / as \/ by default so you shouldn't have to worry about it.

How to encrypt php variable in javascript?

When I creat a php variable in javascript, I use this method:
var jArray = <?php echo json_encode($myArray); ?>;
It's very good but if i view the source code, ther is my full array in the script area.
My problem is that, my php array contains secret data, and I want to use this data in javascritp.
How can I hide from my sourc code, or what can I do?
I tride javascript obfuscation but it can't work with <?php ?> tag.
Thanks!

Pass server-side variables to Javascript in PHP [duplicate]

This question already has answers here:
Efficient way to Pass variables from PHP to JavaScript [duplicate]
(8 answers)
Closed 9 years ago.
What is the best way to pass a server-side PHP variable to Javascript?
To simplify the problem assume that we have a variable in PHP ($phpVar) and we want to assign its value to a Javascript variable (jsVar)
Javascript files are loaded in html - they are not created dynamic!
Some food for thought:
1. Print with PHP before loading Javascript files:
<script language="javascript" type="text/javascript">
var jsVar= <?php echo $phpVar?>;
</script>
2. Store in DOM (in hidden elements)
a. in PHP:
<span data-name="phpVar" data-value="<?php echo $phpVar?>"></span>
b. Read in Javascript files (assuming jQuery available):
var jsVar= $('span[data-name="phpVar"]').attr('data-value');
3. Ask it with AJAX after page has loaded
Obviosly not the best solution. Doesn't fit to all scenarios and requires an additional request...
In conclusion:
They both seem ugly to me... Is there a better approach?
Is there any frameworks that can handle this dependecies? Please keep server reconfiguration minimal.
The best approach would be providing an "internal API" requested via AJAX from client side.
Doing this way you can keep your sides separated.
After this, the fastest way is printing in a shared file the values you want to share (as you wrote in your question).
As a last note: if you carry on with the second way I would suggest you
json_encode()
as a really helpful method to pass arrays and objects from php to javascript.
So if you have your php array:
$array = array( "a" => 1, "b" => 2 );
<script language="javascript" type="text/javascript">
var js_array= <?php echo json_encode( $array ) ; ?>;
</script>
It depends on the situation, but in common, predominantly to use first case. But don't forget about quotes if you pass a string:
<script language="javascript" type="text/javascript">
var jsVar = '<?php echo $phpVar?>';
</script>

Categories

Resources