-
Notifications
You must be signed in to change notification settings - Fork 1
Home
Welcome to the official documentation for initphp/escaper — a small, dependency-free, context-aware output escaper for PHP 7.4+. It implements the rules from the OWASP XSS Prevention Cheat Sheet for the five most common output contexts.
composer require initphp/escaperuse InitPHP\Escaper\Esc;
echo Esc::esc('<script>alert(1)</script>');
// <script>alert(1)</script>htmlspecialchars() alone is not safe in every context. Pasting a "safely escaped" value into an unquoted attribute, a <script> block, a <style> block, or an href will reintroduce XSS even when you think you have escaped it. This package gives you one helper per context, so the rule you apply matches the place the data lands.
| Where the value lands | Method | Wiki page |
|---|---|---|
| Between HTML tags |
escHtml($s) — context 'html'
|
HTML body context |
| Inside an HTML attribute |
escHtmlAttr($s) — context 'attr'
|
HTML attribute context |
| Inside a JavaScript string literal |
escJs($s) — context 'js'
|
JavaScript context |
| Inside a CSS property value |
escCss($s) — context 'css'
|
CSS context |
| Inside a URL component |
escUrl($s) — context 'url'
|
URL context |
There are two entry points: a tiny static facade (Esc) for one-liners, and the underlying object (Escaper) when you want to keep an encoded instance around.
- New? Read Installation, then Quick Start.
- Just want the recipe for one context? Jump straight to the relevant context page above.
-
Choosing between the facade and the class? See
Escfacade andEscaperclass. - Working with non-UTF-8 input? Read Encodings.
- Need to handle failures? See Exceptions.
- Going to production? Read Security Notes.
- Want every method documented? API Reference is exhaustive.
- Coming from 1.x? Read the Migration Guide.
- Stuck on something specific? The FAQ might have it.
- Five purpose-built escapers. One per OWASP context. Same naming, same encoding handling, same exception tree.
- Verified output. A 62-test PHPUnit suite locks the exact byte-for-byte output of every escape rule, including multibyte UTF-8, BMP-overflow code points, control-character handling and the named-entity table.
- Strict failure mode. Encoding-conversion failures raise a typed exception instead of returning an empty string. No silent data loss.
-
PHPStan
level: max, zero issues. Hard to regress without CI catching it. -
Zero runtime dependencies.
ext-ctypeandext-mbstringare the entire footprint.ext-iconvis optional and is preferred when available. -
Tested on PHP 7.4 → 8.4 in CI on every push, against both
--prefer-lowestand--prefer-stabledependency sets.
| Capability | Status |
|---|---|
escHtml() — HTML body context |
✅ |
escHtmlAttr() — quoted, single-quoted and unquoted attrs |
✅ |
escJs() — JavaScript string literal |
✅ |
escCss() — CSS value |
✅ |
escUrl() — RFC 3986 percent-encoding |
✅ |
Recursive escape over arrays (Esc::esc($payload)) |
✅ |
Named-entity preference over numeric refs (", &, …) |
✅ |
| Multibyte UTF-8 input (Turkish, Greek, CJK, …) | ✅ |
| BMP-overflow code points (emoji, surrogate pairs in JS) | ✅ |
C0/C1 control-character replacement (U+FFFD) |
✅ |
| Non-UTF-8 input/output encodings (iso-8859-x, windows-12xx, …) | ✅ |
| Typed exception hierarchy | ✅ |
Esc static facade with per-encoding memoisation |
✅ |
- License: MIT
- Minimum PHP: 7.4 (tested on 7.4, 8.0, 8.1, 8.2, 8.3, 8.4 in CI)
-
Runtime dependencies:
ext-ctype,ext-mbstring -
Optional:
ext-iconv(preferred when present) -
Packagist:
initphp/escaper - Source: github.com/InitPHP/Escaper
- Issues: github.com/InitPHP/Escaper/issues
- Discussions: github.com/orgs/InitPHP/discussions
-
Security:
SECURITY.md
If something on this wiki is unclear, ambiguous, or wrong, please open an issue — documentation fixes are reviewed eagerly.
Getting Started
Entry Points
Output Contexts
Reference
Production
Migration & Help