A problem with 'http://...' when using PHP to write JS

I am trying to get PHP to write some JS so I can manipulate an array client-side. Having worked though difficulties with escaping quotes and apostrophes, I seem to have hit a problem with 'http:// ’ because my JS is seeing the ‘//’ as a comment.

I tried escaping the ‘//’ as ‘\/\/’ but that gave me a link in the final HTML like 'http:\/\/example.com which tries to work as a relative not absolute URL. Same problem with the entity code ‘&#47

That may be sufficient information for someone to tell me how to deal with the problem, but in case not, here’s a bit more detail:

The link starts life as part of a PHP variable:


Example WITH URL:

$phocr = "<a class='" . $phocrcolor . "' href='http://example.com/bird/' target='_blank'>&copy; " . $year . " Nick Name</a>";

Example without URL (which works OK):

$phocr = '&copy; ' . $year . ' Nick Name';

It’s then written (with other stuff) into a JS array using a PHP loop:



echo "img_array[" . $i . "] = '<img src=\\'pan/" . $panimgs[$keys[$i]] . ".jpg\\' alt=\\'\\' /><h1 class=\\'" . $hdgcolor . "\\'>Welcome to Mull &amp; Iona</h1><h5 class=\\'" . $tagcolor . "\\'>" . $tagline . "</h5><p class=\\'phocr\\'>" . $phocr . "></p><h6 class=\\'imgcap\\'>" . $imgcaps[$keys[$i]] . "</h6>';\
";


I’ve left out a lot of detail here, suffice it to say there are other similar items, so I (should) end up with a JS array containing HTML statements. It works for those items that have the Copyright notice but don’t have the URL.
With the URL I get an error message in the Console: “Syntax Error: missing ; before statement”, which I’ve traced to the ‘//’ being taken as a comment.

When it works a typical JS array value looks like this:

img_array[2] = '<img src=\\'pan/marblequarry.jpg\\' alt=\\'\\' /><h1 class=\\'dark\\'>Welcome to Mull &amp; Iona</h1><h5 class=\\'dark\\'>Mull - The Wildlife Capital of Scotland</h5><p class=\\'phocr\\'>&copy; 2014 Tim Dawson></p><h6 class=\\'imgcap\\'>Old marble quarry, Iona</h6>';

The next job is to select which value to display according to a media query. I’ve yet to tackle that, but have a method in mind. I need to solve the problem above first.

The problem you’re having is that the $phocr variable does not escape it’s single quotes (the ones encasing the link), and so when this value is concatenated to your JavaScript string (which is delimited by single quotes), then it breaks out of the literal string value. This can be seen below (I’ve generated some dummy data in-place of the variables):


img_array[0] = '<img src=\\'pan/img.jpg\\' alt=\\'\\' /><h1 class=\\'black\\'>Welcome to Mull &amp; Iona</h1><h5 class=\\'red\\'>tagline</h5><p class=\\'phocr\\'><a href='http://example.com/bird/' target='_blank'>&copy; 2011 Nick Name</a>></p><h6 class=\\'imgcap\\'>imgcaps</h6>';

Notice how the PHP syntax highlighting (which works fine in this case for simple JS code) turns the string orange after the output of the line, because of the unescaped single quote after the href attribute. This is where your syntax error comes from, since the JS engine is expecting a semi-colon to terminate the string.

The legibility of your code could also be greatly increased by using the sprintf and printf functions:


$phocr = sprintf('<a class="%s" href="http://example.com/bird/" target="_blank">&copy; %s Nick Name</a>', $phocrcolor, $year);

printf('img_array[%d] = \\'<img src="pan/%s.jpg" alt="" /><h1 class="%s">Welcome to Mull &amp; Iona</h1><h5 class="%s">%s</h5><p class="phocr">%s</p><h6 class="imgcap">%s</h6>\\';'."\
", $i, $panimgs[$keys[$i]], $hdgcolor, $tagcolor, $tagline, $phocr, $imgcaps[$keys[$i]]);  

Thank you. I’m embarrassed that I didn’t work that out for myself. I’ve escaped the single quotes in the $phocr variable and it works.

As to the formatting, you’re right.The code was entirely legible when the PHP was just making HTML because each statement had its own line. But the JS thought each line was a new statement, so I had to string it all together to get it to work. I’ve never got to grips with printf, but I will now.