No, it's usually a bad practice.
The problem
Any time you echo something from PHP into JavaScript what's happening is that you're trying to generate valid JavaScript code. There is no generic guarantee that you do produce syntactically and semantically valid JavaScript code that also does what you want. It might be easier to guess whether individual instances of code are going to work but it's definitely not a guarantee. Take for example the following code
var someVariable = '<?php echo $someOtherVariable ?>';
This seems like it should work. And indeed it will if $someOtherVariable
doesn't contain a newline or a single apostrophe. However, if it contains O'Brian
or Hello\nWorld
the generated JavaScript code would be invalid in either case:
Early terminating of a string literal leads to invalid code after it:
var someVariable = 'O'Brian';
Invalid multiline string:
var someVariable = 'Hello
World';
Looking at the code and determining whether the code is correct right now and will remain correct becomes very hard. What if the format of the data you're echoing changes? What if you get some data you didn't expect?
To generalise, the issue is that you don't have a complete JavaScript source code. The source code is only complete when a user visits the page and the backend produces it for them. Until then it's in limbo and it's unknown whether it will work.
Impeded code analysis
Not only is it hard for humans to determine how a code would behave, but automated tools that are there to help you might also suffer. Some examples
- Syntax highlighters may break because of the mix of the two languages. This is often the first line of defence against defective code. For example, look at the line that says
'O'Brian'
- you'd see that the highlighting is inconsistent between 'O'
and Brian';
.
- Tools that analyse code for correctness like ESLint or Tern.js among others will not be able to analyse code that's not there. Is
var someVariable = '<?php echo $someOtherVariable ?>")';
syntactically correct JavaScript? We, as humans, cannot say, an automated tool that merely follows some rules is completely unable to guess what the generated code would be.
- Tools that extract code metrics would similarly have a problem as they may not be able to parse the real JavaScript code produced.
Hard to test code
Automatic testing also suffers when you mix the two languages. You can test the code but you need to first need to boot up a PHP environment with enough data in order to generate you JavaScript code and then run tests on the JavaScript code. This is a full integration test with a lot of edge cases to cover and situations to account for. Unit test that focuses on only JavaScript and only PHP would be vastly simpler and you can make sure each fulfils their part of the contract first before checking how they work together.
Hard to debug
What all the above means is that when something happens that breaks JavaScript, you wouldn't be likely to know or even suspect. It's only going to break for some users only some of the time. How many would report it and how accurate the reports would be would vary but in my experience - don't expect much. So, if you'd know that something doesn't work is questionable to begin with. Moreover, even if you do find out that it doesn't work, you'd now have to track down which mixed JavaScript+PHP line is it. Unless there is a single one, you'd need to spend a non-zero time of investigation to find where it goes wrong. And another non-zero amount of time to find why. All that would likely happen after you've developed the application. Maybe a week, maybe a year. In the best case scenario it was you who wrote the code, so while it's still going to be quite hard, you might have some idea about where to start. However, you might have inherited this code. Or somebody else could have inherited it from you.
Bundling
Modern JavaScript is often passed through tools to produce a compact set of files from it. The bundling process will read the JavaScript source and produce a minified version of it. This can suffer if the JavaScript source is incomplete as the compilation happens before any user has ever interacted with the site.
member_id
to always be an integer then<?php echo (int)$_SESSION["member_id"] ?>
is advisable. In general you cannot trust the contents of a variable to produce JS compliant syntax without implementing various guardrails for anticipated data."\u2028\u2029"
was legal JSON but illegal JS; but as of ES5/modern web browsers, that's legal (and have the same meaning) in JavaScript as well; there's another difference between json and js though, they have slightly different interpretation of[{"__proto__": []}]
, apparently. TIL!