在JavaScript代码中转义<?php?

I have to echo the below JavaScript code with using only one <?php tag. How to escape <?php inside the echo?

<script type="text/javascript">

function drawLatestTen() {
    var data = google.visualization.arrayToDataTable(<?php echo json_encode( $json ); ?>);

    var ac = new google.visualization.ComboChart(document.getElementById('ipt_dolt_ten_stat'));
    ac.draw(data, {
        title : '<?php _e( 'Last 30 days form submission statistics', 'ipt_dolt' ); ?>',
        height : 300,
        vAxis : {title : '<?php _e( 'Submission Hits', 'ipt_dolt' ) ?>'},
        hAxis : {title : '<?php _e( 'Date', 'ipt_dolt' ); ?>'},
        seriesType : 'bars',
        series : {<?php echo count( $json[0] ) - 2; ?> : {type : 'line'}},
        legend : {position : 'top'},
        tooltip : {isHTML : true}
    });
}

</script>

so the result is:

<?php echo '<script type="text/javascript">

function drawLatestTen() {
    var data = google.visualization.arrayToDataTable(<?php echo json_encode( $json ); ?>);

    var ac = new google.visualization.ComboChart(document.getElementById(\'ipt_dolt_ten_stat\'));
    ac.draw(data, {
        title : \'<?php _e( \'Last 30 days form submission statistics\', \'ipt_dolt\' ); ?>\',
        height : 300,
        vAxis : {title : \'<?php _e( \'Submission Hits\', \'ipt_dolt\' ) ?>'},
        hAxis : {title : \'<?php _e( \'Date\', \'ipt_dolt\' ); ?>\'},
        seriesType : \'bars\',
        series : {<?php echo count( $json[0] ) - 2; ?> : {type : \'line\'}},
        legend : {position : \'top\'},
        tooltip : {isHTML : true}
    }); ?>
}

</script>'; ?>

Mixing php / js can be a bit confusing because the quotes can intersect.

Notice that we're using " and '. You might want to echo with " or with ' depending on what you need to accomplish. echoing with " in php allows you to use variables in the string, ie: echo "hello {$username}" the lamdas ({}) aren't required, but many devs prefer them.

Here's an incomplete example to get you started. You just echo it all at once and concatenate with . for strings in php.

<?php 
$title = translate( 'Submission Hits', 'ipt_dolt' );
$date = translate( 'Date', 'ipt_dolt' );
echo '
<script type="text/javascript">

function drawLatestTen() {
    var data = google.visualization.arrayToDataTable( '. json_encode( $json ) .' );

    var ac = new google.visualization.ComboChart(document.getElementById('ipt_dolt_ten_stat'));
    ac.draw(data, {
        title : '<?php _e( 'Last 30 days form submission statistics', 'ipt_dolt' ); ?>',
        height : 300,
        vAxis : {title : "'. $tite .'"},
        hAxis : {title : "'.$date.'"}, // notice two quotes, double to denote a string in js and singles to break/concatenate the php output. (that's where things get tricky.)
        seriesType : 'bars',
        series : { '. (count( $json[0] ) - 2) .' : {type : 'line'}},
        legend : {position : 'top'},
        tooltip : {isHTML : true}
    });
}
</script>'; ?>

Edit: Special thanks to @wh1t3h4ck5 & @jh1711 for helping me tweak this.

As @admcfajn answered, that is the popper way to solve it but sometimes I have to do these changes through thousands lines of code so I usually change it using regex. I ended up with this solution:

  • Replace all <?php tags with ';
  • Replace all ?> tags with echo '
  • In JavaScript code blocks, escape the single quote ' using \'
  • In JavaScript code blocks, break the long echo function into several echo functions.

I did it this way and it works fine.

echo '
<script type="text/javascript">

function drawLatestTen() {
    var data = google.visualization.arrayToDataTable(';
        echo json_encode($json);
echo ');

    var ac = new google.visualization.ComboChart(document.getElementById(\'ipt_dolt_ten_stat\'));
    ac.draw(data, {
        title : \'';
        _e('Last 30 days form submission statistics', 'ipt_dolt');
echo '\',
        height : 300,
        vAxis : {title : \'';
        _e('Submission Hits', 'ipt_dolt');
echo '\'},
        hAxis : {title : \'';
        _e('Date', 'ipt_dolt');
echo '\'},
        seriesType : \'bars\',
        series : {';
        echo count($json[0]) - 2;
echo ' : {type : \'line\'}},
        legend : {position : \'top\'},
        tooltip : {isHTML : true}
    });
}

</script>
        ';