imap_mail_move() 不适用于特殊字符 (äüö...)



我正在使用imap_mail_move((将电子邮件从一个文件夹移动到另一个文件夹。这很好用,但如果涉及到文件夹名称中的特殊字符,则不然。我确定我需要对名称进行编码,但所有测试都不成功。

有人有好主意吗?提前谢谢。

class EmailReader {
    [...]
    function doMoveEmail($uid, $targetFolder) {
        $targetFolder = imap_utf8_to_mutf7($targetFolder);
        $return = imap_mail_move($this->conn, $uid, $targetFolder, CP_UID);
        if (!$return) {
            $this->printValue(imap_errors());
           die("stop");
        }
        return $return;
    }
    [...]
}

在脚本中调用函数

[...]
$uid = 1234;
$folderTarget1 = "INBOX.00_Korrespondenz";
$this->doMoveEmail($uid, $folderTarget1);
$folderTarget2 = "INBOX.01_Anmeldevorgang.011_Bestätigungslink";
$this->doMoveEmail($uid, $folderTarget2);
[...]

第一次调用(folderTarget1(的执行运行良好。

执行 secound 调用 (folderTarget2( 时会创建一个错误:

[TRYCREATE] Mailbox doesn't exist: INBOX.01_Anmeldevorgang.011_Bestätigungslink (0.001 + 0.000 secs).

注1

如果我调用 imap_list((,文件夹的名称显示为

"INBOX.01_Anmeldevorgang.011_Besta&Awg-tigungslink" (=$val)
using: 
$new = mb_convert_encoding($val,'UTF-8','UTF7-IMAP')
echo $new; // gives --> "INBOX.01_Anmeldevorgang.011_Bestätigungslink"
but:
$new2 = mb_convert_encoding($new,'UTF7-IMAP', 'UTF-8')
echo $new2; // gives --> "INBOX.01_Anmeldevorgang.011_Best&AOQ-tigungslink"

注2

我使用以下脚本检查了每种可能的编码,但没有一个与 imap_list(( 返回的值匹配。

// looking for "INBOX.01_Anmeldevorgang.011_Besta&Awg-tigungslink" given by imap_list().
$targetFolder = "INBOX.01_Anmeldevorgang.011_Bestätigungslink";
foreach(mb_list_encodings() as $chr){
  echo mb_convert_encoding($targetFolder, $chr, 'UTF-8')." : ".$chr."<br>";
}

您的文件夹名称(与服务器上一样(Besta&Awg-tigungslink未进行规范编码:

&Awg-解码为组合字符。 使用一些方便的python来查找它:

import base64
import unicode data
x = base64.b64decode('Awg=').decode('utf-16be'); # equals added to satisfy base64 padding requirements
unicodedata.name(x)
# Returns 'COMBINING DIAERESIS'

这与它前面的 a 相结合以显示 ä。

编码器返回更常见的预组合形式:

x = base64.b64decode('AOQ=').decode('utf-16be')
unicodedata.name(x)
# Returns: 'LATIN SMALL LETTER A WITH DIAERESIS'

这是 ä 的直接表示。

通常,使用 IMAP 文件夹时,会传递原始名称,并且仅转换文件夹名称以进行显示。 如您所见,从字形到 unicode 中的编码不一定有单向映射。

令我惊讶的是,PHP 在编码时似乎确实在执行规范化步骤;我希望往返相同的数据以返回相同的东西。

我创建了一个解决方法,它可以帮助我使用 UTF8 值并将其转换为原始(原始(IMAP 文件夹名称。

    function getFolderList() {
        $folders = imap_list($this->conn, "{".$this->server."}", "*");
        if (is_array($folders)) {
            // Remove Server details of each element of array
            $folders = array_map(function($val) { return str_replace("{".$this->server."}","",$val); }, $folders);
            // Sort array
            asort($folders);
            // Renumber the list
            $folders = array_values($folders);
            // add UTF-8 encoded value to array
            // this is needed as the original value is so wiered, that it is not possible to encode it
            // with a function on the fly. This additional utf-8 value is needed to map the utf-8 value
            // to the original value. The original value is still needed to do some operations like e.g.:
            //  - imap_mail_move()
            //  - imap_reopen()
            // ==> the trick is to use normalizer_normalize()
            $return = array();
            foreach ($folders as $key => $folder) {
                $return[$key]['original'] = $folder;
                $return[$key]['utf8']     = normalizer_normalize(mb_convert_encoding($folder,'UTF-8','UTF7-IMAP'));
            }

            return $return;
        } else {
            die("IMAP_Folder-List failed: " . imap_last_error() . "n");
        }
    }

相关内容

  • 没有找到相关文章

最新更新