首页 > 解决方案 > 带破折号的 imap_search

问题描述

我有一个文件名,它是基于使用 imap_header() 的电子邮件主题行生成的。具体来说:

$header = imap_header($imap, $m);
$email[$m]['subject'] = imap_utf8($header->subject);
$name = str_replace('/','~~',$email[$m]['subject']) . '[|].txt';  //replace slashes to avoid confusion in filenames 
file_put_contents($name, $contents)

在不同的脚本中,我处理文件,然后我想根据主题行查找电子邮件并将其移动到不同的电子邮件文件夹。

$ffileA = explode('[|]',$ffile);
$subj = $ffileA[0];
$ms = imap_search($imap, 'SUBJECT "'.str_replace('~~','/',$subj).'"');
foreach($ms as $msg){
    imap_mail_move($imap, $msg, 'INBOX/Processed');
}
imap_expunge($imap); 

这在几乎所有情况下都有效,但我刚刚遇到一封电子邮件,其主题为 =?utf-8?B 编码(因此需要 imap_utf8($header->subject) )并且在主题行中有一个短划线. 在服务器上,文件名有 - 而不是破折号,并且 imap_search 找不到关联的电子邮件。我假设我需要将其转换回 imap_search 能够找到的格式。我可能可以使用 str_replace 对这个特殊字符执行此操作,但我更希望能够处理类似奇怪字符的一般情况(例如,使用 iconv() 或用某种类型的通配符替换奇怪的字符或使用正则表达式拆分 SUBJECT 搜索)。

有任何想法吗?

标签: phputf-8imap

解决方案


我将其修复如下:

$ffileA = explode('[|]',$ffile);
$subj = $ffileA[0];
$ssubj = preg_replace("/[^[:ascii:]]+/",'" SUBJECT "',$subj);
$ms = imap_search($imap, 'SUBJECT "'.str_replace('~~','/',$ssubj).'"');
foreach($ms as $msg){
    imap_mail_move($imap, $msg, 'INBOX/Processed');
}
imap_expunge($imap); 

这实质上将主题搜索拆分为任何非 ASCII 子字符串,因此

SUBJECT "abcdefâ€xyz" 

变成

SUBJECT "abcdef" SUBJECT "xyz"

由于 imap_search 有一个隐含的 AND,这是相当安全的,尽管不可否认,主题 'xyzabcdef' 也可以匹配,所以它并非完全没有风险


推荐阅读