PHP 8.4: base64_encode
function supports padding-less Base64 encoding
PHP provides a base64_encode
and base64_decode
function pair to encode any string or a byte-sequence to a base64-encoded string, or to decode a base64-encoded string back to a string or a byte-sequence.
Base64 is a ubiquitous binary-to-text encoding, and PHP follows the RFC 4648 standard that defines the alphabet and padding standards. It's a 6-bit encoding that encodes index 0 (000000)
to 63 (111111
) using A-Z, a-z, 0-9, and +
/
characters.
Because Base64 is a 6-bit encoding, and the original decoded values are 8-bit, every three source bytes are encoded into four characters. Base64 encoding adds a =
character to the end of the encoded text to make sure the length is a multiple of four. However, this padding character is not essential to decoding, because the length of the missing bytes can be inferred from the encoded text length.
In PHP, the base64_encode()
function adds the padding character by default. The base64_decode()
function can decode both padded and unpadded Base64-enoded text.
In PHP 8.4, the base64_encode()
function supports a second parameter named $padding
to toggle the padding behavior. When $padding = false
, the base64_encode
function does not add padding. By default value is $padding = true
, which is implicitly the default behavior on older PHP versions.
This change introduces no backward-compatibility issues because in PHP 8.4 and later, PHP continues to add Base64 padding by default. the difference is that PHP 8.4 and later supports turning off the padding functionality.
The
base64_decode
function in all PHP versions can decode both padded and unpadded Base64-encoded strings. It requires no additional parameters.
With this change, the base64_encode
function signature has changed:
- function base64_encode(string $string): string {}
+ function base64_encode(string $string, bool $padding = true): string {}
base64_encode('http://php.watch');
// aHR0cDovL3BocC53YXRjaA==
base64_encode('http://php.watch', padding: true);
// aHR0cDovL3BocC53YXRjaA==
base64_encode('http://php.watch', padding: false);
// aHR0cDovL3BocC53YXRjaA
Backward Compatibility Impact
This change involves adding an optional parameter the base64_encode
function. Because the default value for this parameter $padding = true
, and older PHP versions also add Base64 padding by default, all PHP versions including 8.4 and later continue to add Base64 padding.
Passing the $padding
parameter to the base64_encode
function in PHP 8.3 and older versions result in an ArgumentCountError
exception because older versions only expect 1 parameter:
ArgumentCountError: base64_encode() expects exactly 1 argument, 2 given
Padding-less Base64-encoding in User-land PHP
A custom Base64-encode function can trivially bring this feature to older PHP versions. On performance-critical applications that call base64_encode
function several times, it might be useful to utilize Engine-inlined functions, which can be inspected to use fewer Opcodes.
if (\PHP_VERSION_ID >= 80400) {
$encoded = \base64_encode($value, padding: false);
}
else {
$encoded = \str_replace('=', '', \base64_encode($value);
}