Context-aware output escaper for PHP. Safely render untrusted user input inside HTML, HTML attributes, JavaScript, CSS and URLs.
htmlspecialchars() is not enough on its own. Each output context — an HTML
body, an attribute, a JavaScript string literal, a CSS value, a URL parameter
— needs its own escaping rules, and using the wrong one can leave you exposed
to XSS even when you think you have escaped your data.
initphp/escaper implements the rules from the
OWASP XSS Prevention Cheat Sheet
for the five most common contexts, behind a small, dependency-free API.
composer require initphp/escaper- PHP 7.4 or newer
ext-ctypeext-mbstring(required);ext-iconvis used when present and preferred over mbstring
use InitPHP\Escaper\Esc;
echo Esc::esc('<script>alert(1)</script>');
// <script>alert(1)</script>
echo Esc::esc('faketitle onmouseover=alert(1);', 'attr');
// faketitle onmouseover=alert(1);
echo Esc::esc('"; alert(1); var x="', 'js');
// \x22\x3B\x20alert\x281\x29\x3B\x20var\x20x\x3D\x22
echo Esc::esc('</style><script>alert(1)</script>', 'css');
// \3C \2F style\3E \3C script\3E alert\28 1\29 \3C \2F script\3E
echo Esc::esc('" onmouseover="alert(1)', 'url');
// %22%20onmouseover%3D%22alert%281%29Esc::esc() also accepts arrays and recurses into them, so escaping a whole
request payload at the view boundary is a one-liner:
$safe = Esc::esc($_GET, 'html');public static function esc(
array|string $data,
string $context = 'html',
?string $encoding = null
): array|string;| Argument | Description |
|---|---|
$data |
A string, or an array (which is escaped recursively). |
$context |
html, attr, js, css, url, or raw (returns input unchanged). |
$encoding |
Output encoding. null resolves to UTF-8. See Encodings. |
Throws InitPHP\Escaper\Exception\InvalidContextException for unknown contexts.
For lower-level use, instantiate Escaper directly. Each instance is bound to
one encoding and exposes one method per context:
use InitPHP\Escaper\Escaper;
$escaper = new Escaper(); // utf-8
$escaper = new Escaper('windows-1252');
$escaper->escHtml($string);
$escaper->escHtmlAttr($string);
$escaper->escJs($string);
$escaper->escCss($string);
$escaper->escUrl($string);The docs/ directory contains a per-context walkthrough with
examples, do-and-don't guidance and security notes:
- Getting started
- HTML body context
- HTML attribute context
- JavaScript context
- CSS context
- URL context
- Encodings
- Exceptions
- Security notes
Output escaping prevents XSS but it is not a substitute for input validation, authentication, or authorisation. It is also context-sensitive: the JavaScript escaper assumes the caller wraps the result in quotes, the HTML attribute escaper assumes the value is used as a single attribute value, and so on. Read the per-context docs before mixing contexts.
Contributions are welcome. Please read the org-wide CONTRIBUTING guide for the workflow, coding standards and test expectations.
A typical loop is:
git clone https://github.com/InitPHP/Escaper.git
cd Escaper
composer install
composer ci # cs-check + phpstan + phpunitIndividual steps are also available:
| Command | What it does |
|---|---|
composer test |
Run PHPUnit |
composer stan |
Run PHPStan (max level) |
composer cs-check |
Report PHP-CS-Fixer violations, no changes |
composer cs-fix |
Apply PHP-CS-Fixer changes |
If you discover a security issue, please follow the disclosure process documented in SECURITY.md rather than opening a public issue.
Released under the MIT License. © InitPHP.