Escape Characters
What Is an Escape Character? In simple terms: An escape character is a backslash ( 0) placed inside a string to give the next character a special meaning — for example, \n means "new line", and \"` me
What Is an Escape Character?
In simple terms: An escape character is a backslash (0) placed inside a string to give the next character a special meaning — for example, \nmeans "new line", and\"` means "a double quote that does not end the string".
Technically: An escape sequence is a combination of a backslash and one or more characters that PHP's parser replaces with a different character when it reads a string literal. Escape sequences are processed only in string literals in your source code — in double-quoted strings and heredoc. Single-quoted strings and nowdoc support almost none of them.
Why Escape Sequences Exist
Some characters cannot be typed directly into a string, or would confuse the parser if they were:
- Quotes that match the string's delimiter would end the string early.
- Invisible characters such as newlines, tabs, and null bytes are hard or impossible to type and see.
- The dollar sign starts variable interpolation in double-quoted strings.
- Characters by code — any byte or Unicode character can be written by its numeric value.
Escape Sequences in Double-Quoted Strings
| Sequence | Meaning |
|---|---|
\n | Line feed (newline), ASCII 10 |
\r | Carriage return, ASCII 13 |
\t | Horizontal tab, ASCII 9 |
\v | Vertical tab, ASCII 11 |
\e | Escape character, ASCII 27 (used for terminal colors) |
\f | Form feed, ASCII 12 |
0 | A single backslash |
\$ | A literal dollar sign (prevents interpolation) |
\" | A literal double quote |
\0 to \777 | A byte written in octal (1–3 digits), e.g. \101 = A |
\x0 to \xFF | A byte written in hexadecimal (1–2 digits), e.g. \x41 = A |
\u{...} | A Unicode character by code point, encoded as UTF-8 (PHP 7.0+), e.g. \u{20B9} = ₹ |
Example
<?php
echo "Name:\tAsha\nCity:\tMadurai\n";
echo "She said \"Hello\".\n";
echo "Price: \$499\n";
echo "Backslash: \\\n";
echo "Letter A: \x41 \101\n";
echo "Rupee: \u{20B9} Elephant: \u{1F418}\n";
Output
Name: Asha
City: Madurai
She said "Hello".
Price: $499
Backslash: \
Letter A: A A
Rupee: ₹ Elephant: 🐘
How Each Line Works
\tinserts a tab and\nstarts a new line.\"places a double quote inside a double-quoted string without ending it.\$499prints a dollar sign. Without the backslash, PHP would try to interpolate a variable — but$4is not a valid variable name, so here it would actually print correctly. With text such as"\$price", the escape is essential, because$pricewould otherwise be replaced by the variable's value.0produces one backslash. The final\nthen adds a newline.\x41(hexadecimal 41) and\101(octal 101) both represent the byte 65, which isA.\u{20B9}and\u{1F418}produce Unicode characters by their code points, encoded as UTF-8 bytes. This is useful for characters that are hard to type or invisible, such as a non-breaking space (\u{00A0}).
Escape Sequences in Single-Quoted Strings
Single-quoted strings recognize only two escape sequences:
| Sequence | Meaning |
|---|---|
\' | A literal single quote |
0 | A literal backslash |
Every other backslash is printed as-is.
Example
<?php
echo 'It\'s PHP' . "\n";
echo 'Line one\nStill line one' . "\n";
echo 'Network path: \\\\server\share' . "\n";
echo 'Cost: $50' . "\n";
Output
It's PHP
Line one\nStill line one
Network path: \\server\share
Cost: $50
Explanation
\'inserts a single quote.\nis not converted; the backslash andnare printed literally.01becomes two backslashes (2), while\sis not a known sequence, so it stays as\s.$50is printed literally because single quotes never interpolate.
Comparing the Length
<?php
var_dump(strlen("\n"));
var_dump(strlen('\n'));
Output
int(1)
int(2)
"\n" is a single newline character. '\n' is two characters: a backslash and the letter n.
Unknown Escape Sequences
If a backslash is followed by a character that is not a recognized escape, PHP keeps both the backslash and the character.
<?php
echo "Pattern: \d+ \w+\n";
echo "Path: C:\Users\Kavin\n";
Output
Pattern: \d+ \w+
Path: C:\Users\Kavin
\d, \w, \U, and \K are not PHP escape sequences, so they appear unchanged. The final \n is still converted to a newline.
This leniency is convenient but risky: whether a backslash survives depends on the character after it. The next section shows how that causes bugs.
The Windows Path Problem
<?php
$path = "C:\new_reports\test.txt";
echo $path;
Output
C:
ew_reports est.txt
Why This Happens
Inside double quotes, \n became a newline and \t became a tab. The path is corrupted, and any attempt to open the file fails. Paths whose folders happen to start with other letters (\Users) work, so the bug appears only for certain folder names — which makes it hard to notice.
Fixes
<?php
$path1 = 'C:\new_reports\test.txt'; // single quotes: no escapes
$path2 = "C:\\new_reports\\test.txt"; // escaped backslashes
$path3 = 'C:/new_reports/test.txt'; // forward slashes
echo $path1 . "\n" . $path2 . "\n" . $path3 . "\n";
Output
C:\new_reports\test.txt
C:\new_reports\test.txt
C:/new_reports/test.txt
PHP on Windows accepts forward slashes in file paths, so / is the most portable choice. For paths built in code, use DIRECTORY_SEPARATOR or simply /, and build paths from known-safe parts such as __DIR__ . '/reports/test.txt'.
Note: A single-quoted string cannot end with a single backslash:
'C:\folder\'is a parse error, because\'is read as an escaped quote. Write'C:\folder0'or use forward slashes.
Line Endings: \n, \r\n, and PHP_EOL
Different systems use different characters to mark the end of a line:
| Line Ending | Characters | Used By |
|---|---|---|
| LF | \n | Linux, macOS, Unix; the standard inside PHP and most web content |
| CRLF | \r\n | Windows text files; required by HTTP headers, email (SMTP) headers, and the CSV standard (RFC 4180) |
PHP_EOL is a constant containing the line ending of the operating system PHP runs on ("\n" on Linux and macOS, "\r\n" on Windows).
When to Use Each
- Terminal output and local log files:
PHP_EOLor"\n". - Protocols with fixed rules (HTTP, email headers, CSV for other systems):
"\r\n"explicitly, because the protocol — not the server's OS — defines the format. - HTML pages: newlines only affect the source; use
<br>or block elements for visible line breaks.
<?php
$lines = ["Order 1001", "Order 1002", "Order 1003"];
file_put_contents(__DIR__ . '/orders.txt', implode(PHP_EOL, $lines) . PHP_EOL);
This writes each order on its own line using the native line ending of the server.
Escape Sequences in Heredoc and Nowdoc
- Heredoc behaves like a double-quoted string: escape sequences and variables are processed, but double quotes do not need escaping.
- Nowdoc behaves like a single-quoted string, but with no escape sequences at all — not even
\'or0.
<?php
$name = "Bala";
echo <<<TEXT
Hello "$name",\tthis line has a tab.
Price: \$250
TEXT;
echo "\n";
echo <<<'RAW'
Nothing is processed here: $name \t \n \\
RAW;
Output
Hello "Bala", this line has a tab.
Price: $250
Nothing is processed here: $name \t \n \\
Nowdoc is ideal for blocks of code, regular expressions, or templates that contain many backslashes and dollar signs. Both syntaxes are covered in Heredoc and Nowdoc.
Escaping in Regular Expressions
Regular expressions use backslashes heavily (\d, \s, 0). Writing patterns in double quotes means PHP processes the backslashes first, before the regex engine sees them.
<?php
$text = "Price: $499.99";
preg_match('/\$(\d+\.\d{2})/', $text, $match);
echo $match[1] . "\n";
Output
499.99
In single quotes, \$, \d, and 0 reach the regex engine unchanged. In double quotes, "\$" would be converted to $ by PHP before the regex engine receives it, so the pattern would mean "end of string" instead of "a literal dollar sign" — and the match would fail.
Rule: always write regular expressions in single quotes.
Escaping User Input in Patterns: preg_quote()
When a pattern includes text from a variable, special regex characters in that text must be escaped:
<?php
$search = "1.5+2";
echo preg_quote($search, '/') . "\n";
var_dump(preg_match('/' . preg_quote($search, '/') . '/', "Result: 1.5+2"));
Output
1\.5\+2
int(1)
preg_quote() adds backslashes before characters that have special meaning in regular expressions (such as . and +). The second argument is the pattern delimiter, which also needs escaping.
Terminal Colors With \e
In command-line scripts, \e starts ANSI escape codes that many terminals interpret as formatting instructions:
<?php
echo "\e[32mSuccess:\e[0m Import completed\n";
echo "\e[31mError:\e[0m 3 rows failed\n";
echo "\e[1mBold text\e[0m\n";
Output (in a supporting terminal)
The word Success: appears in green, Error: in red, and the last line in bold. \e[0m resets formatting so the remaining text uses the default style.
| Code | Effect |
|---|---|
\e[0m | Reset |
\e[1m | Bold |
\e[31m | Red text |
\e[32m | Green text |
\e[33m | Yellow text |
These codes are meaningful only in terminals. In a browser or a log file, they appear as unreadable characters, so use them only in CLI output.
String Escape Sequences vs Output Escaping
There are two different ideas that are both called "escaping", and they are easy to confuse:
| String Escape Sequences | Output Escaping | |
|---|---|---|
| Purpose | Write special characters in your PHP source code | Make data safe for a destination (HTML, SQL, URL, shell) |
| When it happens | When PHP parses the string literal | At runtime, on data (often from users) |
| Example | "Line\n" | htmlspecialchars($comment) |
Backslashes in your source code do nothing to protect data. If a user submits <script>, no escape sequence in your code changes that value; you must escape it for the place where it is used.
Escaping Data for Each Context
| Destination | Function | Example Result |
|---|---|---|
| HTML content and attributes | htmlspecialchars($s) | <b> → <b> |
| URL path segment | rawurlencode($s) | my file.pdf → my%20file.pdf |
| URL query value | urlencode($s) or http_build_query() | a b&c → a+b%26c |
| JavaScript / JSON | json_encode($value) | He said "hi" → "He said \"hi\"" |
| SQL | Prepared statements (not escaping) | Values are sent separately from the query |
| Shell argument | escapeshellarg($s) | my file.txt → 'my file.txt' |
| Regular expression | preg_quote($s, '/') | 1.5+2 → 10512 |
Example: JSON Escaping
<?php
$data = ['message' => 'He said "Hi"', 'path' => 'a/b', 'city' => 'சென்னை'];
echo json_encode($data) . "\n";
echo json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . "\n";
Output
{"message":"He said \"Hi\"","path":"a\/b","city":"\u0b9a\u0bc6\u0ba9\u0bcd\u0ba9\u0bc8"}
{"message":"He said \"Hi\"","path":"a/b","city":"சென்னை"}
json_encode() escapes quotes so the JSON stays valid. By default it also escapes / and converts non-ASCII characters to \uXXXX sequences; both forms are valid JSON. The flags produce more readable output when the JSON is stored or displayed as UTF-8.
Warning:
addslashes()adds backslashes before quotes, but it is not a safe way to prevent SQL injection, because it does not account for the database's character set and quoting rules. Use prepared statements for all SQL that includes data.
Common Mistakes
Using \n in Single Quotes
Effect: A literal \n appears instead of a line break.
Fix: Use double quotes or PHP_EOL: 'Line' . PHP_EOL.
Windows Paths in Double Quotes
Effect: \n, \t, \r, \v, \f, and \e inside paths turn into control characters.
Fix: Use single quotes, double backslashes, or forward slashes.
Writing Regular Expressions in Double Quotes
Effect: PHP consumes escapes such as \$ before the regex engine sees them, changing the pattern.
Fix: Use single quotes for patterns.
Ending a Single-Quoted String With a Backslash
Effect: Parse error — \' escapes the closing quote.
Fix: Use 0 at the end.
Expecting \n to Create Visible Line Breaks in HTML
Effect: The browser shows everything on one line.
Fix: Use nl2br(), <br>, or block-level HTML elements.
Confusing Source-Code Escapes With Data Escaping
Effect: User input is inserted into HTML or SQL unprotected.
Fix: Apply the context-specific function (htmlspecialchars(), prepared statements, json_encode(), and so on).
Best Practices
- Use single quotes for strings that contain backslashes or dollar signs literally: paths, regular expressions, SQL with placeholders.
- Use double quotes when you need
\n,\t,\u{...}, or variable interpolation. - Prefer forward slashes in file paths, even on Windows.
- Use
PHP_EOLfor local text output and\r\nwhere a protocol requires it. - Use nowdoc for large blocks of literal text.
- Escape data at output time for its specific context; never rely on
addslashes()for SQL.
Official reference: https://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.double