使用php中的fsockopen与gmail imap服务器通信的问题

时间:2011-08-25 19:33:09

标签: php stream gmail imap fsockopen

我可以使用php中的imap函数进行通信,也可以使用命令行中的openssl进行通信,我只是想在php中尝试这样做fsockopen()。 我的代码是:

<?php

$sock=fsockopen('ssl://imap.gmail.com', '993',$errno, $errstr);
if(!$sock){
   echo $errstr;
}
else{
   fputs($sock,"a LOGIN user@gmail.com password\r\n");
   $out=fgets($sock,2000);
   fclose($sock);
   echo $out;
}

?>

问题是我在$ out

中得到了服务器的第一个响应
      * OK Gimap ready for requests from **.***.63.101 jj5if832612pbc.164 

当我用fgets的while循环更改代码时,它会继续加载,并且在结束时间内没有显示任何内容。

  <?php

  $sock=fsockopen('ssl://imap.gmail.com', '993', $errno, $errstr);
  if(!$sock){
      echo $errstr;
  }
  else{
      fputs($sock,"a LOGIN user@gmail.com password\r\n");
      while(!feof($sock)){
      $out.=fgets($sock,2000);
      }
 fclose($sock);
 echo $out;
 }

 ?>

我希望在输入登录凭据后看到$ out中服务器的回复。 我可以使用openssl从命令行查看我的电子邮件,所以我认为问题不在于我对imap的处理。 也许我错过了一些关于文件流的基本知识。

感谢。

2 个答案:

答案 0 :(得分:0)

你的循环挂起的原因是因为feof永远不会返回true,因为套接字处于活动状态,直到服务器关闭连接。如果等待的时间足够长,最终循环将因服务器回答“* BYE连接已关闭”而中断。

fputs($sock,"a LOGIN user@gmail.com password\r\n");

如果您在登录命令之前使用了“a”,我使用的方法可能会非常不愉快,因此将“a”更改为“1a23ef”或其他任何内容,以便在获取数据时不会破坏循环太早了,还记得在每个新命令之前使用相同的键,并带有以下内容:

fputs($sock,"a1fd20 LOGIN user@gmail.com password\r\n");
while(true){
 $r = fgets($sock);
  $out .= $r;
  if(strpos($r, 'a1fd20 ') === 0){
   break;
  }
}
echo $out;

这与FETCH 1:1 RFC822命令相当不错,但是如果正在获取的消息在位置0中具有字符串“a1fd20”,则循环仍然会过早地中断(我认为不会发生这种情况) !)。

答案 1 :(得分:-1)

我认为使用标准PHP库与IMAP交互会更好。 看http://www.php.net/manual/en/book.imap.php