Skip to content

PHP Tutorial PHP Security

Output Escaping

Lesson 297 of 369 2 min read By Deepak Paswan Updated Oct 5, 2026

Escaping means converting special characters so they are treated as plain text in the place where the data will be used. The right escaping depends on where the data goes. There is no single “make it safe” function.

Where the data goesWhat to use
HTML text and quoted attributeshtmlspecialchars()
A URL query valueurlencode() or http_build_query()
A URL path partrawurlencode()
JavaScript (inside a <script>)json_encode() with JSON_HEX_* flags
JSON outputjson_encode()
An SQL queryPrepared statements
A shell commandescapeshellarg(), or better, avoid shell commands
CSVQuote and guard against formulas
An email headerRemove CR and LF characters

HTML

index.php
PHP
<?php
$name = "O'Reilly & <Sons>";

echo "<p>Hello, " . htmlspecialchars($name, ENT_QUOTES, "UTF-8") . "</p>";
Output
OUTPUT
<p>Hello, O&#039;Reilly &amp; &lt;Sons&gt;</p>

URL parts

index.php
PHP
<?php
$search = "php & mysql";
$user = "ana/ben";

echo "/search?q=" . urlencode($search) . "\n";
echo "/users/" . rawurlencode($user) . "/profile\n";
echo "/list?" . http_build_query(["tag" => "a b", "page" => 2]);
Output
OUTPUT
/search?q=php+%26+mysql
/users/ana%2Fben/profile
/list?tag=a+b&page=2

HTML and URL together

A link needs both: URL-encode the value, then HTML-escape the whole attribute.

index.php
PHP
<?php
$term = "salt & pepper";

$url = "/search?q=" . urlencode($term);

echo '<a href="' . htmlspecialchars($url, ENT_QUOTES, "UTF-8") . '">Search</a>';
Output
OUTPUT
<a href="/search?q=salt+%26+pepper">Search</a>

JavaScript

index.php
PHP
<?php
$user = ["name" => "Ana", "bio" => "</script><b>"];

echo "<script>const user = " . json_encode($user, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT) . ";</script>";
Output
OUTPUT
<script>const user = {"name":"Ana","bio":"\u003C\/script\u003E\u003Cb\u003E"};</script>

Never build JavaScript by joining strings into inline event handlers (onclick="..."). Pass data through data- attributes (escaped for HTML) and read it in a script file.

Email headers

index.php
PHP
<?php
function headerSafe(string $value): string
{
    return str_replace(["\r", "\n"], "", $value);
}

echo headerSafe("Hello\r\nBcc: attacker@example.com");
Output
OUTPUT
HelloBcc: attacker@example.com

Without removing the line breaks, an attacker can inject extra headers (such as Bcc:) into the email. Better still, use a mail library that handles it.

Where to escape

Escape at output, as late as possible. Store the original text. If you escape before saving, you end up with double-escaped text (&amp;amp;), and the data is wrong for every other use (an email, a PDF, JSON).

Template engines do it for you

  • Twig and Blade escape {{ variable }} by default. You must opt out to print raw HTML.
  • Plain PHP does not. You have to remember htmlspecialchars() every time, so use a helper like h(), and make it a habit.

Test a template for missing escapes

Search your code for echo $ and <?= $ that is not wrapped in an escape function. Each one is a question: where did that value come from?

warning
Escaping once, in the wrong place
htmlspecialchars() protects HTML only. An escaped value inside a <script> or an SQL query is still dangerous. Match the escaping to the destination.