1

我不完全理解这一切是如何工作的,但我收到了这个错误:

致命错误:第 213 行 /Users/andrew/Sites/myApp/library/Zend/Mail/Transport/Smtp.php 中允许的 8388608 字节内存大小已用尽(试图分配 261858 字节)

我在运行 MAMP 的 Mac 上本地运行此代码。不确定这是否与它有关。这是我的代码,基本上:

$config = array('ssl' => 'tls', 'port' => 587, 'auth' => 'login', 'username' => 'username', 'password' => 'password');
    $smtpConnection = new Zend_Mail_Transport_Smtp('smtp.gmail.com', $config);

    foreach ($subscribers as $subscriber) {
        $message = new Zend_Mail('utf-8');
        $message->setFrom('my@mailinglist.com', 'Mailing List')
                ->addTo($subscriber->email)
                ->setSubject($subject)
                ->setBodyText($body);
        $attachment = $message->createAttachment(file_get_contents($filepath));
        $attachment->type = 'application/pdf';
        $attachment->filename = $filename;
        $message->send($smtpConnection);
    }

但是,订阅者越多,这个数字就越高,这个修复只能帮助这么久:

ini_set("memory_limit","12M");

我需要弄清楚如何向数百人发送带有附件的电子邮件。这是我想出的其他东西,但只设置密件抄送而不是收件人地址似乎有点笨拙:

$message = new Zend_Mail('utf-8');
    $message->setFrom('my@mailinglist.com', 'Mailing list')
            ->setSubject($subject)
            ->setBodyText($body);
    $attachment = $message->createAttachment(file_get_contents($filepath));
    $attachment->type = 'application/pdf';
    $attachment->filename = $filename;

    foreach ($subscribers as $subscriber) {
        $message->addBcc($subscriber->email);
    }
    $message->send($smtpConnection);

但是,即使这样做,我也需要指定“memory_limit”。你能指出我正确的方向吗?有什么我没有做的吗?

4

3 回答 3

2

无需为每条消息创建新附件。只需创建一次,然后在每次发送时附加。

$config = array('ssl' => 'tls', 'port' => 587, 'auth' => 'login', 'username' => 'username', 'password' => 'password');
$smtpConnection = new Zend_Mail_Transport_Smtp('smtp.gmail.com', $config);

$attachment = new Zend_Mime_Part(file_get_contents($filepath));
$attachment->type = 'application/pdf';
$attachment->disposition = Zend_Mime::DISPOSITION_ATTACHMENT;
$attachment->filename = $filename;

foreach ($subscribers as $subscriber) {
    $message = new Zend_Mail('utf-8');
    $message->setFrom('my@mailinglist.com', 'Mailing List')
            ->addTo($subscriber->email)
            ->setSubject($subject)
            ->setBodyText($body);
    $message->addAttachment($attachment);
    $message->send($smtpConnection);
}
于 2009-04-23T13:52:12.673 回答
2

我猜你的pdf大约是250Kbytes?您发送的每封电子邮件都会将其读入内存一次。不。读一遍。:) 它也可能是 Zend 框架中的一种编码方式。

  • 循环之前调用 file_get_contents()
  • 只要您的服务器可以处理它,就将内存限制设置得更高(我会说是 32-128 MB)
  • unset() 你的变量 - 应该强制 php 对它进行 GC(理论上)
  • 您可以重用 $message 对象(丑陋的 hack,但如果 Zend 进行某种文件编码并且它使用大量内存,则可以节省字节)

我还会做一个 cron-job 来发送电子邮件,并确保每封电子邮件(或对它的引用)与状态一起存储在数据库中。这样,如果您达到另一个内存限制或错误,您将不会发送重复的邮件。

于 2009-04-23T12:31:01.463 回答
0

我在内存限制和通过一个 SMTP 连接发送大量消息时遇到了类似的问题。Zend_Mail_Protocol_Abstract将其内部日志保存在内存中。日志中记录了所有邮件请求。日志随着每条发送的消息而增长。您有时必须调用 $protocol->resetLog() 。(这取决于每条消息的数据量。您可以通过 memory_get_usage() PHP 函数检查您的内存使用情况。)尝试这样的事情:

  $transport = new Zend_Mail_Transport_Smtp();
  $protocol = new Zend_Mail_Protocol_Smtp('localhost');
  $protocol->connect();
  $protocol->helo('localhost');
  $transport->setConnection($protocol);
  foreach(){
    $mail = new Zend_Mail('utf-8');
    ...
    $protocol->rset();
    $mail->send($transport);
    $protocol->resetLog();  // you don't need to resetLog for each message
  }

这也可能有帮助: http: //framework.zend.com/manual/en/zend.mail.multiple-emails.html

于 2009-06-26T12:00:02.147 回答