chr
Returns a one-byte string for the given code point between 0 and 255.
chr(int $codepoint): string- Added in PHP 4.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$codepoint | int | An integer between 0 and 255. Values outside that range are bitwise AND-ed with 255, i.e. wrapped modulo 256. |
Return value
stringA single-character string containing the byte for the given code point.
Errors
As of PHP 8.5.0 a deprecation notice is emitted when codepoint falls outside the interval [0, 255]; the value is still wrapped modulo 256.
Changelog
- PHP 8.5.0Passing integers outside the interval [0, 255] is deprecated.
- PHP 7.4.0The function no longer silently accepts unsupported code points and casts these to 0.
chr builds a one-byte string from a number. It is the inverse of ord, and the two are usually used together when you are working at the byte level.
When to reach for it
Use it to produce control characters that are awkward to type or easy to mangle in an editor: a tab with chr(9), a carriage return with chr(13), a NUL terminator with chr(0), or a record separator in a fixed-width protocol. It is also handy in loops that generate byte ranges, such as building an alphabet or a lookup table from chr(97) to chr(122).
What trips people up
It returns a byte, not a Unicode character. chr(233) is the single byte 0xE9, which is é in ISO-8859-1 but invalid on its own in UTF-8 — echo it into a UTF-8 page and you get a replacement glyph. For real Unicode use mb_chr, or the literal escape "\u{00E9}".
Out-of-range values wrap rather than error: chr(256) is chr(0) and chr(-1) is chr(255). Since PHP 8.5 that wrapping raises a deprecation notice, so clamp or validate the input yourself.
Example
When to use it
- Insert a tab, carriage return or other control byte into a delimited file without relying on editor whitespace.
- Generate a byte range in a loop, such as an A-Z alphabet or a base-N character table.
- Rebuild a string byte by byte from an array of ordinal values produced by ord.
Frequently asked questions
What is the difference between chr and mb_chr?
chr returns a single byte for a value in 0-255, while mb_chr returns the full multi-byte encoding of a Unicode code point. For anything above 127 in a UTF-8 application you want mb_chr.
What happens if I pass a number bigger than 255 to chr?
The value is wrapped modulo 256, so chr(256) equals chr(0) and chr(321) equals chr(65). Since PHP 8.5 this also emits a deprecation notice, so clamp the value first.
How do I get the number back from a character?
Use ord, which returns the code point of the first byte of a string. ord(chr($n)) returns $n for any $n between 0 and 255.
More examples
Building a byte range
The loop turns the code points 97 to 102 into the string "abcdef", and mapping ord over its characters returns the same numbers — chr and ord are exact inverses for any value in 0-255.
<?php
$alphabet = "";
for ($i = 97; $i <= 102; $i++) {
$alphabet .= chr($i);
}
echo $alphabet, "\n";
echo implode(",", array_map("ord", str_split($alphabet))), "\n";One byte is not one character
chr(233) is a single byte e9, which is not valid UTF-8 on its own. The real UTF-8 é is two bytes, c3a9, and only that one prints correctly on a UTF-8 terminal.
<?php
$byte = chr(233);
$utf8 = "\u{00E9}";
echo strlen($byte), " ", bin2hex($byte), "\n";
echo strlen($utf8), " ", bin2hex($utf8), "\n";
echo $utf8, "\n";Out-of-range values wrap
Passing a value already inside 0-255 is always safe. The helper clamps instead of letting the value wrap modulo 256, which avoids the PHP 8.5 deprecation notice and the surprise of chr(256) silently meaning chr(0).
<?php
var_dump(ord(chr(65)));
var_dump(ord(chr(65 & 255)));
$safe = static fn (int $n): string => chr(max(0, min(255, $n)));
echo bin2hex($safe(300)), " ", bin2hex($safe(-5)), "\n";
Discussion