T
T
toxa822015-03-24 23:22:55
PHP
toxa82, 2015-03-24 23:22:55

How can I decode the file name in a letter?

I'm trying to get attachments to an email. Usually filenames are either not encoded or encoded as:

public 'attribute' => string 'FILENAME' (length=8)
public 'value' => string '=?UTF-8?B?0LfQsNC60L7QvdGLLnR4dA==?=' (length=36)

But I also found a letter in which the file name is in the form:
public 'value' => string 'UTF-8''%D0%9F%D1%80%D0%B0%D0%B7%D0%B4%D0%BD%D0%B8%D1%87%D0%BD' (length=61)

imap_mime_header_decode($value) doesn't help in this case.
I see that this string can be broken by '' and apply urldecode, but I'm afraid that this may break the names of files that are not encoded in this way.
Full dump of the email part obtained from imap_fetchbody():
object(stdClass)[56]
  public 'type' => int 3
  public 'encoding' => int 3
  public 'ifsubtype' => int 1
  public 'subtype' => string 'OCTET-STREAM' (length=12)
  public 'ifdescription' => int 0
  public 'ifid' => int 0
  public 'bytes' => int 55350
  public 'ifdisposition' => int 1
  public 'disposition' => string 'ATTACHMENT' (length=10)
  public 'ifdparameters' => int 1
  public 'dparameters' => 
    array (size=2)
      0 => 
        object(stdClass)[33]
          public 'attribute' => string 'FILENAME*0*' (length=11)
          public 'value' => string 'UTF-8''%D0%9F%D1%80%D0%B0%D0%B7%D0%B4%D0%BD%D0%B8%D1%87%D0%BD' (length=61)
      1 => 
        object(stdClass)[22]
          public 'attribute' => string 'FILENAME*1*' (length=11)
          public 'value' => string '%D0%BE%D0%B5%20%D0%BC%D0%B5%D0%BD%D1%8E%20-%20%E2%84%961.doc' (length=60)
  public 'ifparameters' => int 1
  public 'parameters' => 
    array (size=2)
      0 => 
        object(stdClass)[20]
          public 'attribute' => string 'NAME*0*' (length=7)
          public 'value' => string 'UTF-8''%D0%9F%D1%80%D0%B0%D0%B7%D0%B4%D0%BD%D0%B8%D1%87%D0%BD%D0' (length=64)
      1 => 
        object(stdClass)[53]
          public 'attribute' => string 'NAME*1*' (length=7)
          public 'value' => string '%BE%D0%B5%20%D0%BC%D0%B5%D0%BD%D1%8E%20-%20%E2%84%961.doc' (length=57)

Part of the original letter:
--=_3318071e8a22163e63d59b7e832d6cf5
Content-Transfer-Encoding: base64
Content-Type: application/octet-stream;
name*0*=UTF-8''%D0%9F%D1%80%D0%B0%D0%B7%D0%B4%D0%BD%D0%B8%D1%87%D0%BD%D0;
name*1*=%BE%D0%B5%20%D0%BC%D0%B5%D0%BD%D1%8E%20-%20%E2%84%961.doc
Content-Disposition: attachment;
filename*0*=UTF-8''%D0%9F%D1%80%D0%B0%D0%B7%D0%B4%D0%BD%D0%B8%D1%87%D0%BD;
filename*1*=%D0%BE%D0%B5%20%D0%BC%D0%B5%D0%BD%D1%8E%20-%20%E2%84%961.doc
0M8R4KGxGuEAAAAAAAAAAAAAAAAAAAAPgADAP7/CQAGAAAAAAAAAAAAAAABAAAASgAAAAAAAAAA
EAAATAAAAAEAAAAD+// //AAAAAEkAAAD/////////////////////////////////////////////

Answer the question

In order to leave comments, you need to log in

2 answer(s)
T
toxa82, 2015-03-25
@toxa82

So far I've settled on this one:

if (preg_match('/(%[0-9a-f]{2})+/i', $sFileName)) {
    $sFileName = urldecode($sFileName);
}
if (strpos($sFileName, "''")) {
    $aStr = explode("''", $sFileName, 2);
    if (function_exists('mb_list_encodings')) {
        foreach (mb_list_encodings() as $encoding) {
            if (strcasecmp($aStr[0], $encoding) === 0) {
                $sFileName = $this->iconvCharset($aStr[1], $aStr[0]);
                break;
            }
        }
    }
}

C
Centrino, 2015-03-25
@Centrino

iconv_mime_decode($string,0,"UTF-8");

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question