php imap_open()在连接到localhost时运行缓慢


php imap_open() is running slowly when connecting to localhost

系统信息:运行于CentOS 6.2版(最终版),PHP 5.3.3,Dovecot+postfix安装,Apache/2.2.15(Unix)

连接线:

$mbox = imap_open({'{localhost:143/imap/novalidate-cert}INBOX','un','pw');

更改端口和/或使用ip和域名没有影响。。。

运行imap_open命令通常需要5.5到7秒。。。

你知道我怎样才能让它跑得更快吗?

以下是开始的两个步骤。您需要隔离原因——是PHP还是本地IMAP服务器。这些步骤使用telnetstrace。您可能需要先安装它们:

yum install telnet
yum install strace

首先:使用telnet 在本地测试连接

$ telnet localhost 143
...
  a LOGIN username password

还有延迟吗?如果是-何时:在初始连接时或在LOGIN命令之后?如果出现延迟,则问题与服务器上的IMAP有关,而与PHP无关。

第二:如果通过telnet连接很快,请制作一个最小的PHP脚本,并使用strace 进行调试

<?php
   // save this as imap_test.php
   $mbox = imap_open({'{localhost:143/imap/novalidate-cert}INBOX','un','pw');
?>
$ strace -t -s 200 php ./imap_test.php

将strace的输出保存到文件strace.log:

$ strace -t -s 200 php ./imap_test.php 2>&1 > strace.log
strace writes all its output to stderr.
2>&1 means to combine stderr with stdout, then > to write to the logfile.
If you want to see the output AND write it to a file, use tee:
$ strace -t -s 200 php ./imap_test.php 2>&1 | tee strace.log

你会得到很多产出。试着看看它是否挂在哪里,等待什么。当您看到它挂起时,快速按ENTER键几次通常很有用——这样,在命令完成后,通过在输出中向后滚动可以更容易地定位。

只要有一点耐心(和运气),您应该能够检测PHP在哪里等待,以及等待什么。

编辑:(或接下来发生了什么

一个问题是SSL/TLS导致延迟。添加/notls选项解决了这个问题:

// This should be ok for internal connections to localhost, but you really 
// dont want to disable TLS on an open network
$mbox = imap_open('{localhost:143/imap/notls}INBOX','un','pw');

禁用TLS会导致PHP警告。下面是关于处理它们的讨论。

另一个问题是身份验证方法。基本上php的imap_open将尝试所有协议。人们抱怨了好几年,最后通过在php5.3:[3]中添加一个新参数来修复它

$mbox = imap_open('{localhost:143/imap/notls}INBOX','un','pw',NULL,1,array('DISABLE_AUTHENTICATOR' => array('GSSAPI','NTLM)));

长话短说:从6秒到6毫秒。

[3]https://bugs.php.net/bug.php?id=33500