The cost of escaping quotes in HTML output
A controlled measurement of two htmlspecialchars flag sets, with security semantics kept explicit.
The correctness boundary
What local timing and output-size difference appears when quotes are escaped in addition to angle brackets and ampersands?
Escaping rules depend on output context. Text nodes, quoted attributes, JavaScript and URLs are not interchangeable contexts.
This report exists to quantify overhead while making clear that security semantics outrank the benchmark winner.
Skipping quote escaping may do less work, but it is unsafe for quoted attribute contexts and should not be selected merely for speed.
Measured evidence
What this run shows: ENT_NOQUOTES + substitute has the lower timing number, yet only variants that satisfy the target HTML context belong in the safety decision. The slowest-to-fastest median spread was 3.68% on the measured host.
| Variant | Median | Middle 50% | Operations/s | Additional measure |
|---|---|---|---|---|
| ENT_NOQUOTES + substituteFastest | 23.98 µs | 23.48 µs–24.22 µs | 41,696 | 8,240 output bytes |
| ENT_QUOTES + substitute | 24.87 µs | 24.68 µs–24.92 µs | 40,216 | 9,840 output bytes |
What could go wrong with a timing-only choice?
Do not interpret a faster no-quotes result as a recommendation. In a quoted HTML attribute, failing to escape quotes can break the attribute boundary and create an injection vulnerability.
For general HTML helpers, ENT_QUOTES with the correct encoding is the safer default. Specialized context-aware encoders should be used for JavaScript, CSS and URL contexts.
Implementation checks
- Use ENT_QUOTES for reusable HTML escaping helpers and quoted-attribute output.
- Never choose an escaping mode solely because it benchmarks faster.
- Keep raw untrusted input out of script, style and URL contexts unless encoded for that exact context.
How this boundary was tested
- The same Unicode string with tags, ampersands and double quotes is escaped by both variants.
- Both use UTF-8 and ENT_SUBSTITUTE. One escapes quotes; the other explicitly does not.
- No template engine or response buffering is included.
Open measured environment
- Measurement run
- 2026-07-22T15:23:56+00:00
- PHP
- 8.4.23 (cli)
- Operating system
- Linux 4.18.0-553.85.1.el8_10.x86_64
- Architecture
- x86_64
- Processor
- AMD EPYC-Rome Processor
- Reported host memory
- 15.02 GiB host total
- CLI OPcache
- 0
- PHP memory limit
- 1024M
- Loaded study extensions
- json, openssl, zlib, mbstring, pdo_sqlite
- Timing clock
- hrtime(true)
- Measured rounds
- 7
Scope and unresolved questions
- The study covers HTML escaping only, not JavaScript or CSS encoding.
- It does not test invalid byte sequences beyond ENT_SUBSTITUTE behavior.
Primary documentation
Use these documents to verify the required API, encoding or filesystem behavior. ASAMB supplies the local measurements, not the normative rule.
Inspect or rerun the evidence
The common runner and study-specific fixture are public so the result can be challenged on another PHP host.