2009-04-23 22 views
1

で複数の電子メールを送信するためにZendのメールトランスポートを使用しようとすると、私は完全にこのすべてがどのように機能するかを理解していないが、私はこのエラーを取得しています:Zend Frameworkの:致命的なエラーが発生した添付ファイル

致命的なエラー:許可されたメモリサイズを/Users/andrew/Sites/myApp/library/Zend/Mail/Transport/Smtp.php 213行目にある8388608バイトの空き(261858バイトの割り当てを試みました)

私は実行中のMacでこのコードをローカルで実行していますMAMP。それがそれと関係があるかどうかは分かりません。これは基本的に、私のコードです:より多くの加入者がある

$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('[email protected]', '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"); 

私がする必要があります数百人の人々に添付ファイル付きのメールを送る方法を見つけ出す。ここで私が作ってみたが、それだけで対処するBCCを設定していないと少しハックようだ何か他のものです:

$message = new Zend_Mail('utf-8'); 
    $message->setFrom('[email protected]', '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」を指定する必要があります。あなたはこれを正しい方向に向けることができますか?私がやっていないことはありますか?

答えて

2

私はあなたのpdfが約250Kbytesだと思いますか?あなたは電子メールを送信するたびにそれをメモリに読み込んでいます。しないでください。それを一度読んでください。 :)これはZendフレームワークのエンコーディング機能でもあります。

  • コールのfile_get_contents()一度あなたのループ
  • (私は32から128バイトのラインに沿って言うと思います)はるかに高い限り、サーバーがそれを処理できるように、メモリ制限を設定する前にあなたの変数はPHPで強制的にGCにする必要があります(理論上)
  • $ messageオブジェクトを再利用することができます(醜いハックですが、Zendがある種のファイルエンコーディングを行い、

私はまた、電子メールを送信するためのcron-jobを作成し、各電子メール(またはそれへの参照)がステータスとともにデータベースに格納されていることを確認します。これにより、別のメモリ制限やバグに遭遇した場合に、重複したメールを送信することはありません。

+0

ロットアドバイスはこちら!しかし、(メモリ制限を設定せずに)メールを1通送信するだけで、まだエラーが発生しています。エラーはメモリの制限が現在8Mbに設定されていることを意味し、250Kを超えていますか?私はこれをローカルで(MAMPを使って)実行しています。私はこれを私のコードで32Mbに設定すると、それは私のサーバーが可能なものより少ないでしょうか?より良い解決策を見つけるよりも、この価値を設定することで不利益を蒙っていますか? – Andrew

+0

8Mが小さすぎます。実際、デフォルトのPHP memory_limitはPHP5.2.0時点で16Mです。あなたが非常にローエンドのサーバ/コンピュータを持っていない限り、それを32Mに設定することは全く問題ではありません。個人的には私のワークステーションと私のサーバー(それぞれ4G/2Gメモリ)で128Mを実行しています。あなたの現在のmemory_limitは、ini_get( 'memory_limit')と同じです。あなたの現在の使用法に関しては、memory_get_peak_usage()とmemory_get_usage()。中傷をするのは?イモ、いいえ。使用はまだ受け入れ可能なパラメータの範囲内です。 – tommym

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('[email protected]', 'Mailing List') 
      ->addTo($subscriber->email) 
      ->setSubject($subject) 
      ->setBodyText($body); 
    $message->addAttachment($attachment); 
    $message->send($smtpConnection); 
} 
0

多くのメッセージに対して、メモリ制限と1つの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

関連する問題