views:

14631

answers:

15

What is the easiest way to encode a PHP string for output to a Javascript variable?

I have a PHP string which includes quotes and newlines. I need the contents of this string to be put into a Javascript variable.

Normally, I would just construct my Javascript in a PHP file, ala:

<script>
  var myvar = "<?php echo $myVarValue;?>";
</script>

However, this doesn't work when $myVarValue contains quotes or newlines.

+10  A: 

encode it with JSON

Javier
Probably the easiest way to get this to work 100% of the time. There are too many cases to cover otherwise.
Abyss Knight
Json only works with UTF-8 Charset. So it is not a solution if your website is working in a non UTF-8 Encoding
Nir
@nir: on one hand, i don't know any reason to use any other encoding, on the other hand, a full JSON encoder also manages any needed charset conversion
Javier
A: 

If you use a templating engine to construct your HTML then you can fill it with what ever you want!

Check out XTemplates: http://www.phpxtemplate.org It's a nice, open source, lightweight, template engine.

Your HTML/JS there would look like this:

<script>
    var myvar = {MyVarValue};
</script>
Adam
+4  A: 

Here's one take

<?php 

$jsVar = <<<JS
This is a "sample" javascript variable.
It's purpose is simple.
JS;

define( "ESCAPE_MODE_DOUBLE", 1 );
define( "ESCAPE_MODE_SINGLE", 2 );

function prepareJsStringLiteral( $stringLiteral, $mode )
{
    switch ( $mode )
    {
     case ESCAPE_MODE_DOUBLE:
      $searches = array( '"', "\n" );
      $replacements = array( '\\"', "\\n\"\n\t+\"" );
      break;
     case ESCAPE_MODE_SINGLE:
      $searches = array( "'", "\n" );
      $replacements = array( "\\'", "\\n'\n\t+'" );
      break;
    }
    return str_replace( $searches, $replacements, $stringLiteral );
}

?>

<script type="text/javascript">
    var myvar1 = "<?php echo prepareJsStringLiteral( $jsVar, ESCAPE_MODE_DOUBLE ); ?>";
    var myvar2 = '<?php echo prepareJsStringLiteral( $jsVar, ESCAPE_MODE_SINGLE ); ?>';
</script>

You could even add a 2nd argument to the function to handle the different delimiters (" vs ')

EDIT: I went ahead and expanded the function to handle both delimiting options.

Peter Bailey
why not always escape both quote types?
Mr. Shiny and New
You could - this way, though, it reduces the potential amount of noise in the output, if even only by a little bit.
Peter Bailey
+1  A: 

Take a look at addcslashes function.

Milan Babuškov
+1  A: 

htmlspecialchars

Description

string htmlspecialchars ( string $string [, int $quote_style [, string $charset [, bool $double_encode ]]] )

Certain characters have special significance in HTML, and should be represented by HTML entities if they are to preserve their meanings. This function returns a string with some of these conversions made; the translations made are those most useful for everyday web programming. If you require all HTML character entities to be translated, use htmlentities() instead.

This function is useful in preventing user-supplied text from containing HTML markup, such as in a message board or guest book application.

The translations performed are:

* '&' (ampersand) becomes '&amp;'
* '"' (double quote) becomes '&quot;' when ENT_NOQUOTES is not set.
* ''' (single quote) becomes '&#039;' only when ENT_QUOTES is set.
* '<' (less than) becomes '&lt;'
* '>' (greater than) becomes '&gt;'

http://ca.php.net/htmlspecialchars

Chris MacDonald
Peter Bailey
+3  A: 

Explanation and online testing of escaping client-side and server-side (Javascript / PHP):

JavaScript: Escaping Special Characters

micahwittman
Actually the related http://www.the-art-of-web.com/php/javascript-escape/ is closer to my original requirements.<script type="text/javascript"> alert("<?php echo preg_replace("/\r?\n/", "\\n", addslashes($message)); ?>");</script>
David Laing
+1  A: 
function escapeJavaScriptText($string)
{
    return str_replace("\n", '\n', str_replace('"', '\"', addcslashes(str_replace("\r", '', (string)$string), "\0..\37'\\")));
}
micahwittman
A: 

You can insert it into a hidden DIV, then assign the innerHTML of the DIV to your JavaScript variable. You don't have to worry about escaping anything. Just be sure not to put broken HTML in there.

Diodeus
Javier
No, just don't close your container DIV prematurely.
Diodeus
+2  A: 

You could try

<script type="text/javascript">
    myvar = unescape('<?=rawurlencode($myvar)?>');
</script>
Jacob
+33  A: 

Expanding on someone else's answer:

<script>
  var myvar = <?= json_encode($myVarValue); ?>;
</script>

This does require PHP 5.2.0 or greater.

bobwienholt
If you use UTF-8 that's the best solution by far.
porneL
yep, that's exactly how i do it.
Javier
It is important that the implementation of json_encode escapes the forward slash. If it didn't, this wouldn't work if $myVarValue was "</script>". But json_encode does escape forward slashes, so we're good.
Drew LeSueur
A: 

I found a bit of code on the web that seems to do this really easily.

return strtr($string, array('\\'=>'\\\\',"'"=>"\\'",'"'=>'\\"',"\r"=>'\\r',"\n"=>'\\n','</'=>'<\/'));

Does the trick for me.

Toby Allen
A: 

I have had a similar issue and understand that the following is the best solution:

<script>
    var myvar = decodeURIComponent("<?php echo rawurlencode($myVarValue); ?>");
</script>

However, the link that micahwittman posted suggests that there are some minor encoding differences. PHP's rawurlencode() function is supposed to comply with RFC 1738, while there appear to have been no such effort with Javascript's decodeURIComponent().

pr1001
A: 

Micah's solution below worked for me as the site I had to customise was not in UTF-8, so I could not use json; I'd vote it up but my rep isn't high enough.

function escapeJavaScriptText($string) { return str_replace("\n", '\n', str_replace('"', '\"', addcslashes(str_replace("\r", '', (string)$string), "\0..\37'\"))); }

A: 

I'm not sure if this is bad practice or no, but my team and I have been using a mixed html, JS, and php solution. We start with the PHP string we want to pull into a JS variable, lets call it:

$someString

Next we use in-page hidden form elements, and have their value set as the string:

<form id="pagePhpVars" method="post">
<input type="hidden" name="phpString1" id="phpString1" value="'.$someString.'" />
</form>

Then its a simple matter of defining a JS var through document.getElementById:

<script type="text/javascript" charset="UTF-8">
    var moonUnitAlpha = document.getElementById('phpString1').value;
</script>

Now you can use the JS variable "moonUnitAlpha" anywhere you want to grab that PHP string value. This seems to work really well for us. We'll see if it holds up to heavy use.

ioTus
I have been doing this in my previous projects. Next time, I will try to use jQuery data.
wenbert
A: 

Or...you could simply do this (note the double backslash):

<?php
$myString = "Some string\\nHere's a new line\\n...and Another";
?>
<script type="text/javascript">
alert("<?php echo $myString; ?>");
</script>

Basically, you end up escaping the newline so that JavaScript itself can handle it. Simple, right? It is version, package and browser independent. Enjoy.

Edit: I didn't read this all the first time as I was looking for a solution for newlines (not so much quotes), but basically use backslash to escape certain characters in your strings. You can manually write these in, or write some function that will take care of that for you. The useful thing to remember here is that you can escape special characters like newlines and quotes. To escape backslashes, use 4 backslashes.

Skyler Sully