Obmerk Kronen
Obmerk Kronen

Reputation: 15949

Concatenating PHP and JS while echoing

I have JS with an options var like so :

$output .= 
        '<script type="text/javascript">
         // <![CDATA[

                var options = {
                        render: "canvas", 
                        size: "100",
                        radius: "0.5",
                        };

         // ]]>
         </script>';

But I need to output it ( echo ) with PHP variables and it can not be in a separated file, So I did the output using normal concatenation with a point . e.g. '.$var.'but since my JS needs double quotes " I had put them also into the mix resulting in double-single quote sequence .

var options = {
        render: "'.$q_render.'", // Canvas, Div ,Image
        size: "'.$q_size.'",
        radius: "'. $q_corner_r.'",
        };

And it works as far as my tests goes .

The plot thickens , when I need the specific value of $q_corner_r to be multiplied by a factor :

var options = {
        render: "'.$q_ender.'", // Canvas, Div ,Image
        size: "'.$q_size.'",
        radius: "'. ($q_corner_r )* 3 .'",
        };

Which also works . But the real problem is that I needed to be a decimal value and thus multiple by a decimal factor .

var options = {
        render: "'.$q_ender.'", // Canvas, Div ,Image
        size: "'.$q_size.'",
        radius: "'. ($q_corner_r )* 0.3 .'",
        };

At this point , PHP throws an error , because for all it knows, the decimal point in 0.3 is actually an end concatenation point.

my layman solution to the problem was to wrap the problem in json_encode() and send it to battle naked and defenseless.

radius: "'. json_encode( ($q_corner_r )* 0.1 ) .'",

which , very surprisingly, works ok.

So everything works now ( don´t panic ) - but my doubt remains.

How should I handle this situation ? ( I know I CAN do $qr_corner_r = ($qr_corner_r )* 0.1 in PHP before the JS .. but SHOULD I ? )

It is only for pure luck ( or stupidity, or a combination of both ) that my code works .

Is there any other solution / method adequate for these situations ?

Are we merely observing a simply bad "wrong escaping" case ? ( or no-escaping-at-all in my case )

Upvotes: 1

Views: 97

Answers (3)

Pebbl
Pebbl

Reputation: 36005

Your main problem is assuming that JavaScript needs it's values wrapped with quotes, this is only required for string values, for numbers — especially ones you are going to use in calculations — you should leave them unquoted.

$output .= 
  '<script type="text/javascript">
   // <![CDATA[

    var options = {
      render: "canvas", 
      size: 100,
      radius: (' . $q_corner_r . ' * 0.3)
    };

   // ]]>
   </script>';

That way JavaScript will interpret them as type Number, allowing you to perform mathematical calculations without have to rely on JavaScript casting string values back to numbers which can give uncertain results.

As a rule, if you are finding that you are getting confused with escaping, or multiple levels of quotes it is better to rethink your approach. The above could be easily handled by way of json_encoding an entire PHP object, and performing the multiplication on the PHP side.

$data = (object) array(
  'render' => 'canvas',
  'size' => 100,
  'radius' => ($q_corner_r * 0.3),
);

$output .= 
  '<script type="text/javascript">
   // <![CDATA[

    var options = ' . json_encode($data) . '

   // ]]>
   </script>';

Upvotes: 1

YAMM
YAMM

Reputation: 602

try that:

$var = ($q_corner_r* 0.3);
$str ="
      var options = {
                render: "'.$q_ender.'", // Canvas, Div ,Image
                size: "'.$q_size.'",
                radius: "'. $var .'",
                };
";

Upvotes: -1

Entoarox
Entoarox

Reputation: 703

The answer is to change your code to look like it does below:

var options = {
    render: "'.$qr_ender.'", // Canvas, Div ,Image
    size: "'.$q_size.'",
    radius: "'. ($q_corner_r * 0.3) .'",
    };

You added the () but did so only around the variable, making them useless.

In effect, you are performing math, so by adding the () you are isolating that piece of math to be calculated before the rest, just the same as in any other math situation.

Upvotes: 1

Related Questions