我正在开发 Symfony 2.7。我必须创建一个邮件客户端来从邮件服务器(IMAP 协议)检索和发送邮件;为此,我使用了php-imap classes和一个 bundle(包含在 composer 中)。但我不确定我应该如何使用它们:我是扩展类来表示我的 Mail 和 Mailbox 对象,还是应该从头开始创建新类?
我不想直接从我的控制器操作 IMAP,我认为处理时间太长。那正确吗?
创建一个“观察者”(由 cron 执行的定期命令)以每 2 分钟左右解析一次新邮件,从中创建新邮件实体并发送等待的邮件,这是一个好主意吗?我可以在扩展 php-imap 类的同时这样做吗?这样我只会使用一个类?但是存储数据库不会太重吗?
仅获取新邮件的正确方法是什么?我是否必须使用特定功能,例如 imap_check,还是通过搜索条件(例如上次检查的日期)来执行此操作?我尝试使用标准“NEW”,但没有成功。
此外,我必须解析的邮箱非常重。我试图用“ALL”标准在其中一个中进行搜索,但处理起来真的很长!我做对了吗?我只需要耐心吗?
这是我为“观察者”功能所做的:
use PhpImap\Mailbox as ImapMailbox;
class GetNewMailsCommand extends ContainerAwareCommand
{
$em = $this->getContainer()->get('doctrine')->getEntityManager();
$mailboxes = $em->getRepository('MIPMailBundle:MailBox')->findAllActive();
foreach ($mailboxes as $mailbox){
$imapBox = new ImapMailbox('{'.$mailbox->getServer().':143/notls/norsh/novalidate-cert}INBOX', $mailbox->getAdress(), $mailbox->getPassword());
if ($mailbox->getMails() == null || empty($mailbox->getMails())){
$mailsIds = $imapBox->searchMailbox('ALL');
if(!$mailsIds) {
$output->writeln($mailbox->getAdress() . " is empty");
}
} else {
$mailsIds = $imapBox->searchMailbox('NEW');
if(!$mailsIds) {
$output->writeln("No new mail for " . $mailbox->getAdress());
}
}
foreach ($mailsIds as $mailId){
$imapMail = $imapBox->getMail($mailId);
$mail = new Mail($mailbox, false);
$mail->setSubject($imapMail->subject);
$mail->setSender($imapMail->fromAddress);
$mail->setCc($imapMail->cc);
$mail->setBcc($imapMail->bcc);
$mail->setToString($imapMail->toString);
$mail->setContent($imapMail->textPlain);
$mail->setDate(new \DateTime($imapMail->date));
foreach ($imapMail->to as $toAddress){
$mail->addRecipient($toAddress);
}
$em->persist($mail);
}
}
$em->flush();
这是我的实体:
class MailBox
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var
*
* @ORM\OneToOne(targetEntity="\MIP\CRMBundle\Entity\Agency", inversedBy="mailBox", cascade={"persist"})
* @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=true)
*/
private $user;
/**
* @var Agency
*
* @ORM\ManyToMany(targetEntity="\MIP\CRMBundle\Entity\Agency", inversedBy="mailBoxShared")
* @ORM\JoinTable(name="mailbox_shared")
*/
private $sharedTo;
/**
* @var
*
* @ORM\OneToMany(targetEntity="Mail", mappedBy="mailBox")
*/
private $mails;
/**
* @var boolean
*
* @ORM\Column(name="active", type="boolean")
*/
private $active;
/**
* @var string
*
* @ORM\Column(name="adress", type="string", length=255)
*/
private $adress;
/**
* @var string
*
* @ORM\Column(name="server", type="string", length=255)
*/
private $server;
/**
* @var string
*
* @ORM\Column(name="password", type="string", length=255)
*/
private $password;
/**
* @var integer
*
* @ORM\Column(name="port", type="integer")
*/
private $port;
/**
* MailBox constructor.
*/
public function __construct()
{
$this->sharedTo = new ArrayCollection();
$this->mails = new ArrayCollection();
}
class Mail
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="sender", type="string", length=255)
*/
private $sender;
/**
* @var array
*
* @ORM\Column(name="recipients", type="json_array", nullable=true)
*/
private $recipients;
/**
* @var string
*
* @ORM\Column(name="toString", type="string", nullable=true)
*/
private $toString;
/**
* @var array
*
* @ORM\Column(name="cc", type="json_array", nullable=true)
*/
private $cc;
/**
* @var array
*
* @ORM\Column(name="bcc", type="json_array", nullable=true)
*/
private $bcc;
/**
* @var string
*
* @ORM\Column(name="subject", type="string", length=255, nullable=true)
*/
private $subject;
/**
* @var \DateTime
*
* @ORM\Column(name="date", type="datetime")
*/
private $date;
/**
* @var string
*
* @ORM\Column(name="content", type="text", nullable=true)
*/
private $content;
/**
* @var
*
* @ORM\OneToMany(targetEntity="MIP\CRMBundle\Entity\File", mappedBy="mail", cascade={"persist", "remove"})
* @ORM\JoinColumn(name="file_id", referencedColumnName="id", nullable=true)
*/
protected $files;
/**
* @var ArrayCollection
*/
private $attached;
/**
* @var MailBox
* @ORM\ManyToOne(targetEntity="MailBox", inversedBy="mails")
* @ORM\JoinColumn(name="mailBox_id", referencedColumnName="id")
*/
private $mailBox;
/**
* @var LabelSticker
*
* @ORM\ManyToMany(targetEntity="\MIP\MailBundle\Entity\LabelSticker", mappedBy="mails")
*/
private $labels;
/**
* @var boolean
*/
private $readed;
/**
* @var boolean
*/
private $sent;
/**
* Constructor
* @param MailBox $mailbox
* @param boolean $readed
*/
public function __construct($mailbox, $readed)
{
$this->files = new ArrayCollection();
$this->date = new \DateTime('now');
$this->mailBox = $mailbox;
$this->readed = $readed;
}
谢谢你的帮助 !