ord

Returns the integer value 0–255 of the first byte of a string.

Signature
ord(string $character): int
  • Added in PHP 4.0

Parameters

ParameterTypeDescription
$characterstringA single-byte character. Passing a string that is not exactly one byte long is deprecated as of PHP 8.5.

Return value

intAn integer between 0 and 255 — the unsigned value of the string's first byte.

Changelog

  • PHP 8.5.0Passing a string which is not exactly one byte long is deprecated; use ord($str[0]) instead.

ord reads the first byte of a string and gives you its numeric value as an unsigned integer from 0 to 255. It is the inverse of chr, and the two together are how you do arithmetic on characters in PHP: chr(ord('a') - 32) is 'A'.

New in PHP 8.5: pass one byte

Historically ord quietly ignored everything after the first byte, so ord('Hello') returned 72. As of PHP 8.5 that emits a deprecation notice telling you to write ord($str[0]). The change catches a real class of bug — code that meant to inspect a whole string but only ever saw its first character. If you have loops that slice with substr($s, $pos) and pass the remainder to ord, switch them to the index form $s[$pos].

Bytes, not characters

ord knows nothing about UTF-8. On a multi-byte character it returns the first byte of the encoding — for 🐘 that is 240, not the code point 128024. When you want the Unicode code point, use mb_ord; when you want to inspect the raw encoding, loop over the bytes with $s[$i].

The typical uses are low-level: checksums, base conversions, sanitising binary data, and deciding whether a byte is printable before echoing it.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Check whether every byte in an imported field is printable ASCII before storing it.
  • Implement a simple Caesar shift or checksum that needs numeric character values.
  • Inspect the raw UTF-8 bytes of a string while debugging an encoding problem.

Frequently asked questions

What is the difference between ord and mb_ord?

ord returns the value of the first byte (0–255); mb_ord returns the Unicode code point of the first character, which can be far larger. Use mb_ord for anything beyond ASCII.

Why does ord give a deprecation notice in PHP 8.5?

Because PHP 8.5 deprecated passing a string longer than one byte — it used to silently look at only the first byte. Change ord($str) to ord($str[0]) to make that intent explicit.

How do I convert a number back into a character?

Use chr($code) for a single byte, or mb_chr($codepoint) when the value is a Unicode code point above 255.

More examples

Bytes versus code points

The elephant emoji is 4 bytes, and ord reports them as 240 159 144 152 — the UTF-8 encoding. mb_ord instead reports 128024, the actual Unicode code point. If you ever see 240 where you expected a meaningful number, you are calling ord on multi-byte text.

Example · php
<?php
$emoji = "\u{1F418}";
echo strlen($emoji), ' bytes', PHP_EOL;

for ($i = 0; $i < strlen($emoji); $i++) {
    echo ord($emoji[$i]), ' ';
}
echo PHP_EOL;
echo mb_ord($emoji), PHP_EOL;

Escaping non-printable bytes

Prints `id\x00name`. str_split hands ord exactly one byte at a time — which is also what PHP 8.5 now wants — and the numeric range test makes the embedded NUL byte visible instead of silently truncating the output in a terminal or log viewer.

Example · php
<?php
$input = "id\x00name";
$clean = '';
foreach (str_split($input) as $byte) {
    $code = ord($byte);
    $clean .= ($code >= 32 && $code < 127) ? $byte : sprintf('\\x%02X', $code);
}
echo $clean, PHP_EOL;

Discussion

  • Be the first to comment on this lesson.