Encodings like Base64 turn raw bytes into plain text you can store or send safely. PHP has base64_encode() and bin2hex(), but they only cover part of the RFC 4648 standard: there's no URL-safe Base64, no way to drop padding, and no Base32 at all. This RFC from Ignace Nyamagana Butera adds a new Encoding namespace with full RFC 4648 support, plus Base58 and Base85.

How it works

Each encoding family gets an encode and a decode function:

  • base16_encode() / base16_decode()
  • base32_encode() / base32_decode()
  • base58_encode() / base58_decode()
  • base64_encode() / base64_decode()
  • base85_encode() / base85_decode()

Because they all live in the Encoding namespace, they don't clash with the existing global functions. Options are passed as enums rather than flags or strings:

use Encoding\Base64;
use Encoding\PaddingMode;
use Encoding\DecodingMode;

use function Encoding\base64_encode;
use function Encoding\base64_decode;

$data = 'This is an encoded string';

echo base64_encode($data);
// "VGhpcyBpcyBhbiBlbmNvZGVkIHN0cmluZw=="

echo base64_encode($data, paddingMode: PaddingMode::StripPadding);
// "VGhpcyBpcyBhbiBlbmNvZGVkIHN0cmluZw"

echo base64_decode("VGhpcyBpcyBhbiBlbmNvZGVkIHN0cmluZw");
// throws UnableToDecodeException, padding is expected

echo base64_decode("VGhpcyBpcyBhbiBlbmNvZGVkIHN0cmluZw", decodingMode: DecodingMode::Forgiving);
// 'This is an encoded string'

The available options:

  • Variant picks the alphabet. Base64 has Standard, UrlSafe and Imap. Base32 has Ascii, Hex, Crockford and Z. Base58 has Bitcoin and Flickr. Base85 has Adobe, Z85 and Git, and you always have to choose one.
  • PaddingMode controls whether the = padding is kept or stripped.
  • DecodingMode is Strict by default. Forgiving normalizes letter case and padding before decoding.
  • TimingMode can be set to Constant, which makes the work take the same time for any input so an attacker can't learn anything from timing it.

Base16 uses uppercase letters by default, as RFC 4648 specifies, while bin2hex() uses lowercase. Spaces, tabs and newlines are ignored when decoding. Invalid input throws UnableToDecodeException or UnableToEncodeException.

What it means for existing code

The Encoding namespace becomes reserved. The existing base64_encode(), bin2hex() and related functions don't change. The RFC mentions they could be deprecated at some point far in the future, but it doesn't propose that.

Where it stands

It's under discussion and targets PHP 8.6. Tim Düsterhus has offered to write the implementation. The poll on the page is a placeholder with no votes.