imap_mail_move() 不适用于特殊字符 (äüö...)
imap_mail_move() not working on special characters (äüö...)
我正在使用 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(),文件夹名称显示为
"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
我使用以下脚本检查了每种可能的编码,但其中 none 与 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组合起来显示ä。
您的编码器return使用更常见的预组合形式:
x = base64.b64decode('AOQ=').decode('utf-16be')
unicodedata.name(x)
# Returns: 'LATIN SMALL LETTER A WITH DIAERESIS'
这是 ä 的直接表示。
通常,当您使用 IMAP 文件夹时,您会传递原始名称,并且只转换文件夹名称以供显示。如您所见,在 unicode 中不一定存在从字形到编码的单向映射。
令我惊讶的是 PHP 似乎在编码时进行了规范化步骤;我希望将相同的数据往返于 return 相同的东西。
我创建了一个解决方法,它可以帮助我使用 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");
}
}
我正在使用 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(),文件夹名称显示为
"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
我使用以下脚本检查了每种可能的编码,但其中 none 与 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组合起来显示ä。
您的编码器return使用更常见的预组合形式:
x = base64.b64decode('AOQ=').decode('utf-16be')
unicodedata.name(x)
# Returns: 'LATIN SMALL LETTER A WITH DIAERESIS'
这是 ä 的直接表示。
通常,当您使用 IMAP 文件夹时,您会传递原始名称,并且只转换文件夹名称以供显示。如您所见,在 unicode 中不一定存在从字形到编码的单向映射。
令我惊讶的是 PHP 似乎在编码时进行了规范化步骤;我希望将相同的数据往返于 return 相同的东西。
我创建了一个解决方法,它可以帮助我使用 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");
}
}