- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我的问题如下:
如果你看下面,你会看到有一个带有消息 ID 的数据结构,然后是包含消息详细信息的最终数据结构,这些信息应该从 imap_fetch_overview
中聚合。消息 ID 来自 imap_thread
。问题是它没有将电子邮件详细信息放在消息 ID 所在的位置。
这是我的数据结构:
[5] => Array
(
[0] => 5
[1] => 9
)
[10] => Array
(
[0] => 10
[1] => 11
)
我想要的是:
[5] => Array
(
[0] => messageDetails for id 5
[1] => messageDetails for id 9
)
[10] => Array
(
[0] => messageDetails for id 10
[1] => messageDetails for id 11
)
这是我到目前为止的代码:
$emails = imap_fetch_overview($imap, implode(',',$ids));
// root is the array index position of the threads message, such as 5 or 10
foreach($threads as $root => $messages){
// id is the id being given to us from `imap_thread`
foreach($message as $key => $id){
foreach($emails as $index => $email){
if($id === $email->msgno){
$threads[$root][$key] = $email;
break;
}
}
}
}
这是其中一封 $emails 的打印输出:
[0] => stdClass Object
(
[subject] => Cloud Storage Dump
[from] => Josh Doe
[to] => jondoe@domain.com
[date] => Mon, 21 Jan 2013 23:18:00 -0500
[message_id] => <50FE12F8.9050506@domain.com>
[size] => 2559
[uid] => 5
[msgno] => 5
[recent] => 0
[flagged] => 0
[answered] => 1
[deleted] => 0
[seen] => 0
[draft] => 0
[udate] => 1358828308
)
如果您注意到,msgno 是 5,对应于 $id
,因此从技术上讲,数据应该填充到最终数据结构中。
此外,这似乎是一种低效的处理方式。
如果您需要任何其他说明,请告诉我。
更新代码
这段代码是我在 php api 上找到的代码和我修复的一些代码的组合。我认为有问题的仍然是 $root
。
$addedEmails = array();
$thread = imap_thread($imap);
foreach ($thread as $i => $messageId) {
list($sequence, $type) = explode('.', $i);
//if type is not num or messageId is 0 or (start of a new thread and no next) or is already set
if($type != 'num' || $messageId == 0 || ($root == 0 && $thread[$sequence.'.next'] == 0) || isset($rootValues[$messageId])) {
//ignore it
continue;
}
if(in_array($messageId, $addedEmails)){
continue;
}
array_push($addedEmails,$messageId);
//if this is the start of a new thread
if($root == 0) {
//set root
$root = $messageId;
}
//at this point this will be part of a thread
//let's remember the root for this email
$rootValues[$messageId] = $root;
//if there is no next
if($thread[$sequence.'.next'] == 0) {
//reset root
$root = 0;
}
}
$ids=array();
$threads = array();
foreach($rootValues as $id => $root){
if(!array_key_exists($root,$threads)){
$threads[$root] = array();
}
if(!in_array($id,$threads[$root])){
$threads[$root][] = $id;
$ids[]=$id;
}
}
$emails = imap_fetch_overview($imap, implode(',', array_keys($rootValues)));
$keys = array();
foreach($emails as $k => $email)
{
$keys[$email->msgno] = $k;
}
$threads = array_map(function($thread) use($emails, $keys)
{
// Iterate emails in these threads
return array_map(function($msgno) use($emails, $keys)
{
// Swap the msgno with the email details
return $emails[$keys[$msgno]];
}, $thread);
}, $threads);
最佳答案
请记住,在 php 中,无论您使用什么函数,最终都会转换为某种循环。但是,您可以采取一些步骤来提高效率,它们在 PHP 5.5 和 5.3/5.4 中有所不同。
执行此操作的最有效方法是将函数拆分为 2 个单独的步骤。在第一步中,您将为电子邮件列表生成键映射。
$keys = array();
foreach($emails as $k => $email)
{
$keys[$email->msgno] = $k;
}
在第 2 步中,您迭代多维 $threads 中的所有值并将它们替换为电子邮件详细信息:
// Iterate threads
$threads = array_map(function($thread) use($emails, $keys)
{
// Iterate emails in these threads
return array_map(function($msgno) use($emails, $keys)
{
// Swap the msgno with the email details
return $emails[$keys[$msgno]];
}, $thread);
}, $threads);
概念验证:http://pastebin.com/rp5QFN4J
匿名函数中关键字use的解释:
为了使用在父作用域中定义的变量,可以使用 use () 关键字将变量从父作用域导入闭包作用域。虽然它是在 PHP 5.3 中引入的,但尚未在官方 PHP 手册中记录。此处 php 的 wiki 上只有草稿文档 https://wiki.php.net/rfc/closures#userland_perspective
此版本中的一项新功能使您能够使用生成器,生成器的内存指纹明显更小,因此效率更高。
生成器中关键字yield的解释:
生成器函数的核心是 yield 关键字。在最简单的形式中,yield 语句看起来很像 return 语句,不同之处在于 yield 不是停止函数的执行并返回,而是为遍历生成器的代码提供一个值并暂停生成器函数的执行。
第一步:
function genetateKeyMap($emails)
{
foreach($emails as $k => $email)
{
// Yielding key => value pair to result set
yield $email->msgno => $k;
}
};
$keys = iterator_to_array(genetateKeyMap($emails));
第二步:
function updateThreads($emails, $threads, $keys)
{
foreach($threads as $thread)
{
$array = array();
// Create a set of detailed emails
foreach($thread as $msgno)
{
$array[] = $emails[$keys[$msgno]];
}
// Yielding array to result set
yield $array;
}
};
$threads = iterator_to_array(updateThreads($emails, $threads, $keys));
关于生成器返回的值的几句话:
生成器返回一个对象,该对象是 SPL 迭代器的一个实例,因此它需要使用 iterator_to_array() 才能将其转换为您的代码所期望的完全相同的数组结构。您不需要这样做,但它需要在生成器函数之后更新您的代码,这可能会更有效率。
概念验证:http://pastebin.com/9Z4pftBH
我生成了一个包含 7000 个线程的列表,每个线程包含 5 条消息,并测试了每种方法的性能(5 次测试的平均值):
Takes: Memory used:
----------------------------
3x foreach(): 2.8s 5.2 MB
PHP 5.3/5.4 way 0.061s 2.7 MB
PHP 5.5 way 0.036s 2.7 MB
虽然您的机器/服务器上的结果可能不同,但概览显示两步法比使用 3 个 foreach 循环快 45-77 倍左右
关于PHP 从多维数组 (IMAP) 创建消息线程的多维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16248448/
我有一堆代码执行 IMAP 命令“search, idle, done, search, idle, done, search, ...”。 是否有可能某些消息在搜索和空闲命令之间到达,因此只能在空闲
(使用IMAP命令,而不借助任何其他邮件程序包) 最佳答案 我不确定您对imap的了解程度如何,但是基本上在登录后,“选择”源邮箱,“复制”邮件,然后“删除”邮件(如果是,则“删除”旧邮箱)现在是空的
我正在编写一个 IMAP 爬虫,它是开源应用程序的一部分,对于增量爬网,我想使用消息 UID 来确定我是否已经看到了特定消息。 现在我找到了 a post从 2007 年开始说 IMAP UID 并不
我注意到 libcurl 支持 IMAP,但在文档和示例中没有找到任何内容 http://curl.haxx.se/libcurl/c/imap.html很穷。有谁知道如何在这个库中使用这个协议(pr
IMAP UID 是否保证为数字?我读过 RFC3501 中的部分,它说: Unique identifiers are assigned in a strictly ascending fashio
IMAP UID 是否保证为数字?我读过 RFC3501 中的部分,它说: Unique identifiers are assigned in a strictly ascending fashio
我正在使用开源 IMAP C# 库 IMapX (http://hellowebapps.com/products/imapx/)。当我试图从收件箱中获取电子邮件时,需要花费很多时间。有没有办法根据接
我正在尝试使用 Limilabs imap 库连接到电子邮件; tcpc = new System.Net.Sockets.TcpClient("imap.gmail.com", 993); 工作
我正在尝试使用 imap 方法通过 php 打开电子邮件,但它给我一个错误无法打开流 {imap.gmail.com:993/imap/ssl}INBOX,这是我的代码 $hostname = '{i
有没有办法确定给定电子邮件地址的 POP 或 IMAP 服务器?我正在为非技术用户构建一个应用程序,我真的不想打扰他们询问他们的 IMAP/POP 服务器。 mail2web.com这样做,但我不确定
如何确定通过 APPEND 添加的消息的 UID到邮箱?通过 STATUS我可以事先得到下一个值的预测,我可以 SEARCH之后,但依赖这些会引入竞争条件,因为可能在这些命令之间添加了其他消息。 最佳
这个搜索查询对我来说似乎有效: UID SEARCH OR ( OR ( OR (FROM "def@gmail.com") (FROM "abc@gmail.com")) (FROM "ghi@gm
我正在使用以下代码以编程方式验证电子邮件。 Properties properties = new Properties(); Session emailSession = Session.getDe
我正在使用 OpenSSL 连接到邮件服务器。 POP3 工作正常,但 IMAP 有问题。基于 CAPABILITY 命令服务器支持 PLAIN、NTLM 和 GSS-API 认证方法。 我想使用 P
我正在使用以下代码建立 IMAP 连接。我想阅读电子邮件。我读了这个文件 link无法从这里继续。 我的代码: #lang racket (define imap-server "*****") (d
在尝试使用 php 的 imap 函数时,我无法连接到 Gmail 的 imap 服务器。我正在使用: $mail = imap_open('{imap.gmail.com:993/imap/ssl/
我试图更好地理解 Gmail API . stated benefits 之一Gmail API 的最大特点是它可以“提供比 IMAP 显着的性能改进”。 Gmail API 和协议(protocol
已结束。此问题正在寻求书籍、工具、软件库等的推荐。它不满足Stack Overflow guidelines 。目前不接受答案。 我们不允许提出寻求书籍、工具、软件库等推荐的问题。您可以编辑问题,以便
我正在制作一个支持 POP3 和 IMAP 的邮件客户端。我正在使用 vmime api 用 C++ 对客户端进行编程。我的问题是:同步邮件的最佳方式是什么? 我认为标识符是个好方法,但我不知道同步邮
我正在制作一个支持 POP3 和 IMAP 的邮件客户端。我正在使用 vmime api 用 C++ 对客户端进行编程。我的问题是:同步邮件的最佳方式是什么? 我认为标识符是个好方法,但我不知道同步邮
我是一名优秀的程序员,十分优秀!