17

How can you get the file extension of a base64 encoded string in PHP?

In my case, this file happens to be an image:

$base64_encoded_string = $_POST['image_base64_string'];

$extension = ??

How can I get the file extension from $base64_encoded_string ?

EDIT: This is NOT part of an upload form so $_FILES data cannot be used here.

Mystical
  • 2,505
  • 2
  • 24
  • 43

5 Answers5

29

Here is a one-liner inspired by @msg's answer:

$extension = explode('/', mime_content_type($base64_encoded_string))[1];
Mystical
  • 2,505
  • 2
  • 24
  • 43
  • 1
    `mime_content_type` expects a filename so this has me confused – msg Sep 23 '18 at 04:39
  • 2
    Apparently, _base64_ data is treated like a file name according to the result I got from my code. – Mystical Sep 23 '18 at 04:41
  • Worked for me. Thanks – Christopher Kikoti Apr 11 '20 at 21:03
  • but... an extnsion behind this code 'data:image/png;base64' is unreliable , right? @Mystical – gumuruh Jun 26 '20 at 17:53
  • Here you can find a way to get something like "application/pdf" But you have to use decode first to get the binary and then use finfo and buffer: $file_content = base64_decode($base64EncodedString, true); $finfo = new \finfo(FILEINFO_MIME_TYPE); $mimeType = $finfo->buffer($file_content); I got it from this response: https://stackoverflow.com/questions/3312607/php-binary-image-data-checking-the-image-type – Wak Jul 19 '22 at 03:19
3

This worked for me

function getBytesFromHexString($hexdata)
{
  for($count = 0; $count < strlen($hexdata); $count+=2)
    $bytes[] = chr(hexdec(substr($hexdata, $count, 2)));

  return implode($bytes);
}

function getImageMimeType($imagedata)
{
  $imagemimetypes = array( 
    "jpeg" => "FFD8", 
    "png" => "89504E470D0A1A0A", 
    "gif" => "474946",
    "bmp" => "424D", 
    "tiff" => "4949",
    "tiff" => "4D4D"
  );

  foreach ($imagemimetypes as $mime => $hexbytes)
  {
    $bytes = getBytesFromHexString($hexbytes);
    if (substr($imagedata, 0, strlen($bytes)) == $bytes)
      return $mime;
  }

  return NULL;
}

$encoded_string = "....";
$imgdata = base64_decode($encoded_string);
$mimetype = getImageMimeType($imgdata);

Source: https://newbedev.com/detecting-image-type-from-base64-string-in-php

2

If this is part of a upload form, you can get the information about the files from the $_FILES variable.

If it's a raw field you can decode it and run it through mime_content_type or equivalent and take a guess.

If you are open to using libraries, you can look into mimey or php-mimetyper.

msg
  • 7,863
  • 3
  • 14
  • 33
2
//This function return the extension from mimetype
function getImageMimeType(string $encodedImage)
{
    $decodedImage = base64_decode($encodedImage);
    return (explode('/', finfo_buffer(finfo_open(), $decodedImage, FILEINFO_MIME_TYPE))[1]);
}
    
$encodedImage = '        ';
$extension = getImageMimeType($encodedImage);
echo $extension;
1

Regex can extract the image type from the base64 header :

                  ┌───┐
$b64 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII";
preg_match("/\/(.*?);/", $b64, $MATCH);
              ↑     ↑
              └─────┘  RETURNS STRING BETWEEN / AND ;
echo $MATCH[1];

It should display png.

Notice the slash must be escaped \/, while semicolon does not require it.