Sunday, June 3, 2012

Pass a PHP string to a Javascript variable (including escaping newlines)


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.


Source: Tips4all

13 comments:

  1. Expanding on someone else's answer:

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


    This does require PHP 5.2.0 or greater.

    ReplyDelete
  2. 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.

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

    ReplyDelete
  4. You could try

    <script type="text/javascript">
    myvar = unescape('<?=rawurlencode($myvar)?>');
    </script>

    ReplyDelete
  5. 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>

    ReplyDelete
  6. 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

    ReplyDelete
  7. 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().

    ReplyDelete
  8. 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'\\")));
    }

    ReplyDelete
  9. The paranoid version: Escaping every single character.

    EDIT: The reason why json_encode() may not be appropriate is that sometimes, you need to prevent " to be generated, e.g.

    <div onclick="alert(???)" />

    ReplyDelete
  10. Take a look at addcslashes function.

    ReplyDelete
  11. 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.

    ReplyDelete
  12. 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.

    ReplyDelete