The correct way is to use the tools of your framework (and its template engine, if available). If you're fiddling with PHP in JS strings, you probably make life harder and more dangerous than necessary.
With plain PHP a common and safe approach is to use
json_encode() as explained here. E.g.:
var foo = <?php echo json_encode($foo, JSON_HEX_QUOT|JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS); ?>
json_encode() returns the JSON representation of a value, hence it's guaranteed to evaulate to a valid object in your JS code and you can just assign it to a variable as shown. But don't omit the additional flags. Depending on the context, an attacker could otherwise use payloads like
</script> to break out of the entire script tag.
htmlspecialchars() you referred to are used for direct HTML output and should not be employed on JS. They would also allow your string to contain line breaks, resulting in a syntax error that might have security consequences.
Talking about frameworks, Wordpress gives you the wrapper
wp_json_encode(), as recommended in this guideline. There might be equivalent functions for your own framework.
Also be aware that with
json_encode() the object is safely prepared for a JS context, but any string you pass can still contain HTML tags that would be unsafe to insert via, say,
innerHTML. (Avoid these two altogether.)
This is silly, but XSS-safe:
Hello, <span id="display"></span>!
<?php $name = $_GET['name']; ?>
var name = <?php echo json_encode($name, JSON_HEX_QUOT|JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS); ?>;
display.textContent = name;