Base64 Encoding & Decoding in PHP
PHP has built-in base64_encode() and base64_decode() functions. They are simple, but URL-safe Base64 requires a manual conversion step.
Basic Usage
<?php
// Encode
$encoded = base64_encode("Hello, world!");
echo $encoded; // "SGVsbG8sIHdvcmxkIQ=="
// Decode
$decoded = base64_decode("SGVsbG8sIHdvcmxkIQ==");
echo $decoded; // "Hello, world!"
// Validate before decoding
$input = "SGVsbG8sIHdvcmxkIQ==";
if (base64_decode($input, true) !== false) {
echo base64_decode($input);
} else {
echo "Invalid Base64";
}
Use the strict parameter: base64_decode($str, true) returns false instead of attempting to decode invalid input. Always pass true when validating user input.
URL-Safe Base64
PHP does not have a built-in URL-safe encoder, but it is easy to implement:
<?php
function base64url_encode(string $data): string {
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
function base64url_decode(string $data): string|false {
// Restore standard Base64 padding
$padded = strtr($data, '-_', '+/');
$padded = str_pad($padded, strlen($padded) + (4 - strlen($padded) % 4) % 4, '=');
return base64_decode($padded, true);
}
echo base64url_encode("Hello, world!"); // "SGVsbG8sIHdvcmxkIQ"
echo base64url_decode("SGVsbG8sIHdvcmxkIQ"); // "Hello, world!"
Encoding Images and Files
<?php
// Encode a file to Base64
function fileToBase64(string $path): string {
$contents = file_get_contents($path);
if ($contents === false) {
throw new RuntimeException("Could not read file: $path");
}
return base64_encode($contents);
}
// Decode Base64 back to file
function base64ToFile(string $encoded, string $outputPath): void {
$decoded = base64_decode($encoded, true);
if ($decoded === false) {
throw new InvalidArgumentException("Invalid Base64 data");
}
file_put_contents($outputPath, $decoded);
}
$encoded = fileToBase64('image.png');
base64ToFile($encoded, 'output.png');
Creating Data URIs
<?php
function fileToDataUri(string $path): string {
$mime = mime_content_type($path) ?: 'application/octet-stream';
$encoded = base64_encode(file_get_contents($path));
return "data:{$mime};base64,{$encoded}";
}
$dataUri = fileToDataUri('logo.png');
// data:image/png;base64,iVBORw0KGgo...
// Use in HTML
echo '<img src="' . htmlspecialchars($dataUri) . '" alt="Logo">';
Handling Large Files with Chunks
<?php
// Stream-encode a large file without loading it all into memory
function encodeFileLarge(string $input, string $output): void {
$in = fopen($input, 'rb');
$out = fopen($output, 'w');
// Read in multiples of 3 bytes (Base64 requires 3-byte chunks)
while (!feof($in)) {
$chunk = fread($in, 57 * 1024); // 57 bytes → 76 Base64 chars
fwrite($out, base64_encode($chunk));
}
fclose($in);
fclose($out);
}
Common Pitfalls
Whitespace in decoded output
<?php
// base64_decode silently ignores some invalid characters.
// Always trim input from untrusted sources:
$clean = preg_replace('/\s+/', '', $userInput);
$decoded = base64_decode($clean, true);
Using base64 in URLs without URL-encoding
<?php
// Standard Base64 in a URL will break:
$encoded = base64_encode("data"); // may contain + / =
$url = "https://example.com/api?token=" . urlencode($encoded); // ✓
// Better: use URL-safe Base64 and skip urlencode entirely:
$url = "https://example.com/api?token=" . base64url_encode("data"); // ✓✓
Test your PHP Base64 encoding
Paste the output of your PHP base64_encode() calls here to verify they decode correctly.