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.

Open base64.dev →