base64_decode

Decodes a MIME base64-encoded string back into its original bytes.

Signature
base64_decode(string $string, bool $strict = false): string|false
  • Added in PHP 4.0

Parameters

ParameterTypeDescription
$stringstringThe base64-encoded data to decode.
$strictoptionalbool= falseWhen true, returns false if the input contains any character outside the base64 alphabet; when false, such characters are silently discarded.

Return value

string|falseThe decoded data, which may be binary, or false on failure.

Errors

Does not throw. Failure is signalled by returning false, and only when strict is true.

base64_decode() reverses base64_encode(), turning the printable base64 alphabet back into the original bytes. The result is a byte string, not necessarily valid UTF-8 text, so echoing it straight to a terminal or a JSON response can produce garbage or an encoding error.

The strict flag matters

By default, decoding is forgiving: anything that is not a base64 character is thrown away and whatever remains is decoded. That means a corrupted or truncated string still returns a plausible-looking result instead of an error. Pass true as the second argument when the input came from outside your system — a query parameter, a webhook body, a cookie — so that malformed data returns false and you can reject it.

Checking the result

Because a valid decode can legitimately produce an empty string, test with === false rather than a truthiness check. In strict mode, whitespace such as newlines is still permitted, which is what makes wrapped MIME output decode cleanly; other stray characters are rejected.

If the encoded value came out of a URL, decode the percent-encoding first with urldecode(), otherwise %2B sequences reach the decoder as literal text.

Example

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

When to use it

  • Read the credentials out of an incoming HTTP Basic Authorization header
  • Turn a base64 payload from a JSON webhook back into the original file bytes
  • Decode the middle segment of a JWT to inspect its claims
  • Validate that a user-supplied token is well-formed base64 before using it

Frequently asked questions

Why does base64_decode return garbage instead of false?

Because the default lax mode discards characters outside the base64 alphabet and decodes whatever is left. Pass true as the second argument to get false on malformed input.

How do I check whether base64_decode failed?

Call it with strict mode on and compare the result with === false. A plain if check is wrong, since a valid empty input decodes to an empty string.

What is the difference between base64_decode and urldecode?

They undo completely different encodings: base64_decode reverses the base64 alphabet, while urldecode reverses percent-encoding in URLs. A base64 string taken from a URL often needs urldecode first, then base64_decode.

More examples

Validating untrusted input safely

The first call returns the string "user:42". The second returns null because strict mode rejected the '!' characters. The third shows why you must compare with === false: an empty input decodes successfully to an empty string, which a truthiness check would have wrongly treated as failure.

Example · php
<?php
function decodeToken(string $token): ?string {
    $decoded = base64_decode($token, true);
    return $decoded === false ? null : $decoded;
}

var_dump(decodeToken('dXNlcjo0Mg=='));
var_dump(decodeToken('not base64!!'));
var_dump(decodeToken(''));

Reading an HTTP Basic Authorization header

Basic auth is just base64 of "user:password" after the scheme word. Splitting on the first colon only (limit 2) is important, because passwords are allowed to contain colons themselves.

Example · php
<?php
$header = 'Basic ' . base64_encode('alice:s3cret');
echo $header, "\n";

[$scheme, $value] = explode(' ', $header, 2);
$decoded = base64_decode($value, true);

[$user, $pass] = explode(':', $decoded, 2);
echo "user=$user pass=$pass\n";

Decoding a JWT payload segment

JWT segments use base64url, so - and _ must be translated back to + and / and the stripped = padding restored before base64_decode will accept them in strict mode. The output is the decoded claims array with sub and name.

Example · php
<?php
$jwt = 'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI0MiIsIm5hbWUiOiJBZGEifQ.sig';
$parts = explode('.', $jwt);

$segment = strtr($parts[1], '-_', '+/');
$segment .= str_repeat('=', (4 - strlen($segment) % 4) % 4);

print_r(json_decode(base64_decode($segment, true), true));

Discussion

  • Be the first to comment on this lesson.