PHP's Base64 functions
PHP has had first-class Base64 support since version 4 through two core functions: base64_encode() and base64_decode(). Both are in the PHP standard library — no extension, no Composer package. They operate on binary-safe strings, which in PHP means "any sequence of bytes" — text, images, PDFs, encrypted ciphertext, all work identically.
base64_encode(string $string): string returns the standard Base64 representation with +, /, and = padding. base64_decode(string $string, bool $strict = false): string|false reverses the encoding; $strict when true causes the function to return false if the input contains characters outside the Base64 alphabet.
Encoding a string
The simplest use case — Base64-encoding a PHP string variable:
encode-string.php
<?php
$input = 'Hello, world!';
$encoded = base64_encode($input);
echo $encoded . PHP_EOL;
// Output: SGVsbG8sIHdvcmxkIQ==
// Round-trip:
$decoded = base64_decode($encoded);
var_dump($decoded === $input); // bool(true)Encoding a file
Read the file's raw bytes and encode. This works for any file type — PDF, ZIP, image, video, executable — because PHP strings are binary-safe:
encode-file.php
<?php
$bytes = file_get_contents('/path/to/document.pdf');
if ($bytes === false) {
throw new RuntimeException('Could not read file');
}
$encoded = base64_encode($bytes);
echo $encoded; // Single continuous line, ~33% larger than input
// Or write to another file:
file_put_contents('document.pdf.b64', $encoded);Streaming for large files
<?php
// For files > 20 MB, stream in chunks to avoid loading everything into memory.
$handle = fopen('/path/to/large.zip', 'rb');
$output = fopen('/path/to/large.zip.b64', 'w');
while (!feof($handle)) {
// Read in 3-byte multiples so Base64 output has no internal padding
$chunk = fread($handle, 3 * 1024);
fwrite($output, base64_encode($chunk));
}
fclose($handle);
fclose($output);Encoding an image (data URI)
To embed an image as a data URI in HTML, combine base64_encode() with the MIME type. PHP's finfo extension can detect the MIME type from the file's magic bytes:
encode-image-datauri.php
<?php
$path = 'logo.png';
$bytes = file_get_contents($path);
$mime = (new finfo(FILEINFO_MIME_TYPE))->file($path);
// $mime is e.g. 'image/png'
$dataUri = 'data:' . $mime . ';base64,' . base64_encode($bytes);
echo '<img src="' . htmlspecialchars($dataUri) . '" alt="Logo" />';
// The image renders inline — no separate HTTP request needed.Encoding JSON
JSON is just a string in PHP, so encoding is identical to encoding any other string. The two-step pattern — json_encode() then base64_encode() — is used constantly in JWT construction, webhook payloads, and API auth:
encode-json.php
<?php
$payload = [
'user' => 'alice',
'role' => 'admin',
'exp' => time() + 3600,
];
$json = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$base64 = base64_encode($json);
echo $base64;
// e.g. eyJ1c2VyIjoiYWxpY2UiLCJyb2xlIjoiYWRtaW4iLCJleHAiOjE3MTcwMDM2MDB9
// Reverse:
$decoded = json_decode(base64_decode($base64), true);
var_dump($decoded);URL-safe Base64 in PHP
PHP does not ship a url-safe Base64 function, but the transformation is a one-liner using strtr() to swap characters and rtrim() to drop padding:
url-safe-base64.php
<?php
function base64UrlEncode(string $data): string {
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
function base64UrlDecode(string $data): string {
$padded = str_pad($data, strlen($data) + (4 - strlen($data) % 4) % 4, '=');
return base64_decode(strtr($padded, '-_', '+/'));
}
// Round-trip with a JWT payload:
$payload = json_encode(['sub' => 'user_123']);
$urlSafe = base64UrlEncode($payload);
echo $urlSafe; // eyJzdWIiOiJ1c2VyXzEyMyJ9
$back = base64UrlDecode($urlSafe);
echo $back; // {"sub":"user_123"}Common pitfalls
Newlines in file input. Older PHP versions and some libraries wrap Base64 output at 76 characters (MIME line-wrapping per RFC 2045). PHP's base64_encode() does not do this by default — it produces one continuous line. If you paste that into an email header, most SMTP servers require line-wrapping. Use chunk_split(base64_encode($data), 76, "\r\n") for MIME conformance.
Type juggling. base64_decode() returns false on failure in strict mode, but returns garbage bytes in non-strict mode. Always call with base64_decode($input, true) when the input is untrusted, and check for false explicitly with ===.
Multi-byte confusion. If you use mb_* functions and mbstring.func_overload is enabled, strlen() counts characters not bytes. This breaks Base64 length assertions. The setting is deprecated as of PHP 7.2 and removed in PHP 8, but legacy codebases may still have it. Never assume strlen($base64) % 4 === 0 without checking the setting.
Related Base64 & Encoding Tools
- Base64 Encoder (Parent Tool) — the underlying encoder used by every variant on this page
- Base64 Encode Online — general-purpose text encoder with copy-to-clipboard
- Text to Base64 — convert plain text or UTF-8 to Base64
- Base64 Encode in JavaScript — btoa(), TextEncoder, and Buffer.from() patterns
- Base64 Encode in Python — base64.b64encode() reference and examples
- Base64 Decoder — reverse the encoding — Base64 back to text or file
- Base64 to Image Converter — decode a data URI back into a viewable image file