base_convert
Converts a number string from one base to another, for any base between 2 and 36.
base_convert(string $num, int $from_base, int $to_base): string- Added in PHP 4.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$num | string | The number to convert. Invalid characters for from_base are silently ignored. |
$from_base | int | The base num is in. Must be between 2 and 36 inclusive. |
$to_base | int | The base to convert num to. Must be between 2 and 36 inclusive. |
Return value
stringnum converted to base to_base, as a string using digits 0-9 and lowercase letters a-z.
Errors
Throws a ValueError if from_base or to_base is outside the range 2 to 36.
Changelog
- PHP 7.4.0Passing invalid characters now generates a deprecation notice. The result is still computed as if the invalid characters did not exist.
base_convert() is the general-purpose radix converter: give it a number as a string, say what base it is written in, and say what base you want back. Digits above 9 are the letters a to z, so base 36 uses the full alphanumeric range. Output letters are always lowercase — call strtoupper() if you need the other form.
When to reach for it
Its niche is bases that have no dedicated function. Base 36 and base 32 are the usual reasons: turning a numeric row id into a short alphanumeric code for a URL, or reading a base-32 token back into an integer. For the four common bases, the dedicated pairs — bindec()/decbin(), octdec()/decoct(), hexdec()/dechex() — are clearer at the call site and do not go through a float.
What trips people up
Precision. Internally the value passes through a double, so anything above roughly 2^53 comes back rounded and a 16-digit hex string will not survive a round trip. For large values use GMP (gmp_init() with a base, then gmp_strval()) or BCMath.
The other surprise is silence: characters that are not valid digits in from_base are dropped rather than rejected, so a typo yields a wrong number instead of an error. Since PHP 7.4 that at least raises a deprecation notice.
Example
When to use it
- Turn a numeric database id into a short base-36 code for a URL.
- Read a base-32 or base-36 voucher code back into an integer.
- Display a value in an unusual base such as base 5 or base 12 for a teaching tool.
Frequently asked questions
Does base_convert() return uppercase letters?
No, it always returns lowercase digits a-z. Wrap the call in strtoupper() if your format requires uppercase, and note that it accepts either case on input.
What is the maximum base base_convert() supports?
36, using the digits 0-9 followed by the letters a-z. Passing a base below 2 or above 36 throws a ValueError.
Why is my large hexadecimal number wrong after base_convert()?
Because the conversion goes through a floating point double, so values above about 2^53 lose precision. Use the GMP extension — gmp_strval(gmp_init($hex, 16), 10) — for exact conversion of large numbers.
More examples
Short base-36 ids from numeric ids
An id of 123456789 becomes the six-character code 21i3v9, and the third column converts it straight back, showing the mapping is reversible at this size. Base 36 packs roughly 1.56 times more value into each character than base 10, so a nine-digit decimal id fits in six characters.
<?php
foreach ([1, 61, 1000, 123456789] as $id) {
$code = base_convert((string) $id, 10, 36);
printf("%-10d -> %-8s -> %d\n", $id, $code, (int) base_convert($code, 36, 10));
}Precision loss on large values
The comparison prints false: a 64-bit hex value exceeds what a double can represent exactly, so the digits come back mangled. The last line shows a 31-bit value converting perfectly, which is why the problem stays hidden in small tests.
<?php
$big = 'ffffffffffffffff'; // 2**64 - 1
$roundTrip = base_convert(base_convert($big, 16, 10), 10, 16);
var_dump($big === $roundTrip);
echo $roundTrip, PHP_EOL;
echo base_convert('7fffffff', 16, 10), PHP_EOL;
Discussion