You can do this with <?= e(<expression-to-escape>) ?>, where e is a function that escapes strings.
Is this more work than writing {{ <expression-to-escape> }}? I guess, but this is what your template library is doing under the hood anyway.
You can do this with <?= e(<expression-to-escape>) ?>, where e is a function that escapes strings.
Is this more work than writing {{ <expression-to-escape> }}? I guess, but this is what your template library is doing under the hood anyway.
Even within templating libraries there are different levels of advancement around context-awareness: e.g. <div onclick="{{ val }}"> is still dangerous in languages like Twig, and is similarly challenging to audit. Alternatives like Latte mitigate this but even Twig is still a large degree easier to work with than vanilla PHP.
"Large PHP application" just means "at scale", in terms of LoC, and - most likely - contributors. Which means (a) potentially anything may be combined in templates by somebody at some point without careful manual code-review, which is difficult to audit at scale, and (b) there are a larger number of files to audit, likely with a degree of complexity to their overall structure, which further adds to that difficulty.
The question is whether it's easy to write vulnerable code.
For PHP it's easy and implicit:
<div><?= some_expression ?></div>
For React it's hard and explicit: <div dangerouslySetInnerHTML={{ __html: someExpression }} />React normally operates in a DOM. It's templates are translated into javascript, and that javascript manipulates the DOM. PHP templates are just outputting strings.
The point here is that PHP templates work with strings as a design choice: there's nothing about PHP as a language that's preventing you from taking a similarly context-aware template-processing approach.