imap_mail_move () не работает со специальными символами (пока ...) - PullRequest
0 голосов
/ 28 апреля 2019

Я использую 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) работает очень хорошо.

Выполнениевторостепенного вызова (folderTarget2) создает ошибку:

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

Примечание 1 :

если я вызываю imap_list (), отображается имя папкиas

"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>";
}

Ответы [ 2 ]

0 голосов
/ 28 апреля 2019

Я создал обходной путь, который помогает мне работать со значениями 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");
        }
    }
0 голосов
/ 28 апреля 2019

Имя вашей папки, как и на сервере, Besta&Awg-tigungslink не канонически закодировано:

&Awg- декодируется как объединяющий символ diaereses.Используя некоторый удобный 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, вы передаете необработанное имя и конвертируете только имя папки для отображения.Как вы можете видеть, не обязательно существует одностороннее сопоставление глифов с кодировками в юникоде.

Меня удивляет, что PHP, похоже, выполняет шаг канонизации при кодировании;Я ожидал бы, что повторное отключение одних и тех же данных вернет одно и то же.

...