Hi,
Thank you for the feedback — you’re absolutely right that
htmlspecialchars() is configurable for good reasons, and that a userland
helper like h() already provides a concise escape hatch today.
However, I’d like to gently push back on two points:
1. <?~ vs <? (~$expr) under short_open_tag=On
You're correct that with short_open_tag=1, <?~ $x ?> would currently be
parsed as <? (~$x) ?>. But in practice:
- short_open_tag has been disabled by default since PHP 5.4 (2012).
- Most modern frameworks and coding standards explicitly discourage its use.
- The <?= short echo tag is always available regardless of
short_open_tag, precisely because it’s treated specially.
If the RFC were to propose <?~ as a new short echo variant (like <?=),
it would follow the same rule: always enabled, independent of
short_open_tag. That would eliminate the ambiguity you mentioned.
2. Why not just use h()?
Yes, h() works — and many projects already define it. But that’s exactly
the problem: everyone reinvents it, often with slightly different flags,
encoding assumptions, or error handling. This leads to:
- Inconsistent escaping across projects or even within the same codebase.
- Junior developers skipping escaping because “it’s not built in”.
- Security relying on project-specific conventions rather than
language-level defaults.
By providing a standard, secure-by-default output tag in core, PHP would:
- Reduce boilerplate.
- Encourage safer habits out of the box.
- Give small projects (e.g., WordPress plugins, scripts, internal tools)
a zero-dependency way to escape safely — without requiring them to
define or remember h().
Think of it like <?= ... ?>: it didn’t add new capability, but it made
the common case easier and more consistent. <?~ ... ?> aims to do the
same for secure output.
That said, I hear your concern about hardcoded flags. If the community
prefers, the escaping behavior could even respect default_charset and a
new html_output_flags ini setting — though I’d argue opinionated
security defaults are better here.
Thanks again for the critique — it’s helping sharpen the idea.
Best regards,
Sergei
On 12/23/25 15:07, Anton Smirnov wrote:
Hi!
On 23/12/2025 11:06, Sergei Issaev wrote:
which compiles to:
```
<?php echo htmlspecialchars($expr, ENT_QUOTES | ENT_SUBSTITUTE |
ENT_HTML5, 'UTF-8'); ?>
```
htmlspecialchars is configurable for a reason and your flags are
arbitrarily different from the function default
- Syntax is currently a parse error → no BC break.
It's not, you forgot about short_open_tag=1, in which case it's
interpreted as <? (~$expr) ?>
I basically see no value over
// included earlier
function h($s)
{
return htmlspecialchars($s, ENT_QUOTES | ENT_HTML5, 'UTF-8');
}
// template
<?= h($user_input) ?>
It's short, it does what you want, it's available today