Signature
base_convert(string $num, int $from_base, int $to_base): stringPurpose
base_convert() takes a number written as a string in one base and returns the same number written as a string in another base. Both bases must be between 2 and 36. That range covers binary, octal, decimal and hexadecimal, plus "base 36", which uses the digits 0-9 and the letters a-z.
Typical uses are showing a value in binary for debugging, turning hexadecimal into decimal, or building short identifiers from a decimal counter. The function works on text, not on PHP integer literals. 'ff' is a string of digits to interpret, not a hex literal.
Signature
Parameters
$num: the number to convert, as a string. For bases above 10, the lettersatozstand for the values 10 to 35. Letters are read case-insensitively, soFFandffare the same number.$from_base: the base that$numis written in. There is no default. It must be from 2 to 36.$to_base: the base to convert into. There is no default. It must be from 2 to 36.
All three arguments are required.
Return value and failure cases
The function returns a string. Letter digits in the result are always lowercase, and the result has no leading zeros. If you need fixed-width output such as 8-bit binary, pad it yourself with str_pad().
The manual says that characters not valid for $from_base are silently ignored in the calculation, and that since PHP 7.4 supplying them is deprecated. The result is still computed as if those characters were not there. In practice this means '1g' read as hexadecimal quietly loses the g and a deprecation notice is raised. Characters such as a minus sign, a decimal point, spaces or separators are invalid digits too. Validate input first if it comes from users.
In PHP 8, a base outside 2 to 36 is rejected with a ValueError, so a bad base is a programming error you should not rely on handling at runtime.
Example 1: hexadecimal to binary
The first example is the classic one from the manual: each hex digit expands to four binary digits.
$hexadecimal = 'a37334';
echo base_convert($hexadecimal, 16, 2), "\n";101000110111001100110100
Example 2: several conversions
This example shows decimal to hex, uppercase input, base 36, and octal to binary. Note that every returned value is a string, even when it looks like a decimal number.
$results = [
'hex' => base_convert('255', 10, 16),
'upper_input' => base_convert('FF', 16, 10),
'base36' => base_convert('zz', 36, 10),
'octal_to_binary' => base_convert('777', 8, 2),
];
echo json_encode($results, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";{"hex":"ff","upper_input":"255","base36":"1295","octal_to_binary":"111111111"}
Example 3: validating before converting
Because invalid characters are not reported as errors, a small wrapper can make conversion stricter. It checks the bases, lowercases the text, and uses strspn() to confirm that every character is a legal digit for the source base.
function safeConvert(string $num, int $from, int $to): ?string
{
if ($from < 2 || $from > 36 || $to < 2 || $to > 36) {
return null;
}
$digits = substr('0123456789abcdefghijklmnopqrstuvwxyz', 0, $from);
$clean = strtolower($num);
if ($clean === '' || strspn($clean, $digits) !== strlen($clean)) {
return null;
}
return base_convert($clean, $from, $to);
}
echo json_encode([
safeConvert('ff', 16, 10),
safeConvert('fg', 16, 10),
safeConvert('101', 2, 10),
safeConvert('12', 2, 10),
safeConvert('10', 1, 10),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";["255",null,"5",null,null]
Edge cases
- Large numbers: the manual warns that precision can be lost, because the conversion relies on PHP's internal float type. A long string of digits may produce a wrong result without any error. For exact big-number work, use an arbitrary-precision approach instead.
- Leading zeros: they are not kept. Converting
'000ff'from base 16 gives the same result as'ff'. - Strings, not integers: you can pass an integer such as
255for$numwhen strict types are off, but it is converted to the string'255'first, so the digits must make sense in$from_base. Prefer passing explicit strings. - Negative and fractional numbers: a leading minus sign or decimal point is not a valid digit, so the function does not handle signs or fractions meaningfully.
Common mistakes
- Treating the result as a number. The result is a string. Comparing
base_convert('10', 2, 10) === 2is false because the result is'2'. - Trusting invalid input. Since bad characters are skipped, user input like
'12'as binary does not fail loudly. Validate first, as in the third example. - Forgetting padding.
base_convert('5', 10, 2)gives101, not00000101. - Using it for huge values. Long hashes or big identifiers can exceed float precision and silently corrupt.
- Passing the bases in the wrong order. The source base comes first, then the target base.
Related functions
bindec(),decbin(),hexdec(),dechex(),octdec()anddecoct()are fixed-base helpers for common conversions.intval()can parse a string in a given base into an integer, and is listed by the manual as a related function.str_pad()helps format fixed-width results.
Recap
base_convert() converts a digit string between bases 2 and 36 and returns a lowercase string without leading zeros. Letters are case-insensitive on input. Invalid characters are ignored with a deprecation notice rather than treated as hard errors, bases outside the range raise a ValueError in PHP 8, and large values can lose precision. Validate input, keep the result as a string, and pad when you need a fixed width.
Tested examples
$hexadecimal = 'a37334';
echo base_convert($hexadecimal, 16, 2), "\n";
101000110111001100110100
$results = [
'hex' => base_convert('255', 10, 16),
'upper_input' => base_convert('FF', 16, 10),
'base36' => base_convert('zz', 36, 10),
'octal_to_binary' => base_convert('777', 8, 2),
];
echo json_encode($results, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
{"hex":"ff","upper_input":"255","base36":"1295","octal_to_binary":"111111111"}
function safeConvert(string $num, int $from, int $to): ?string
{
if ($from < 2 || $from > 36 || $to < 2 || $to > 36) {
return null;
}
$digits = substr('0123456789abcdefghijklmnopqrstuvwxyz', 0, $from);
$clean = strtolower($num);
if ($clean === '' || strspn($clean, $digits) !== strlen($clean)) {
return null;
}
return base_convert($clean, $from, $to);
}
echo json_encode([
safeConvert('ff', 16, 10),
safeConvert('fg', 16, 10),
safeConvert('101', 2, 10),
safeConvert('12', 2, 10),
safeConvert('10', 1, 10),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
["255",null,"5",null,null]