首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >phpmailer在出现较大附件时突然停止

phpmailer在出现较大附件时突然停止
EN

Stack Overflow用户
提问于 2019-05-20 00:49:23
回答 1查看 436关注 0票数 1

Problem

我有一个脚本发送时事通讯给我的联系人。脚本工作良好,如果我没有附件(证明与2,000电子邮件)。

现在,如果我使用附件,脚本也可以正常工作。但仅通过发送大约30封电子邮件。

测试-设置

(loop).

  • attachments: 2文件(总计4,6 MB) -->脚本在50秒后终止(但没有错误消息),并且发送了34封电子邮件,共100封电子邮件,共100封
  • 。(~ 156 MB)。

Test-Variations

  • 在php.ini memory_limit中从100M更改为500M -->不起作用。仍然错误34 emails.
  • putting a sleep(5) after each循环-->没有任何效果。在34封电子邮件后仍然出错。
  • no attachments:发送所有100封电子邮件(约30秒)。
  • no attachments on 2000 emails:所有2000封电子邮件均已发送(约6分钟)。
  • no effect of changing max_execution_time in php.ini。

Assumtions

由于这种行为,我预计会有记忆问题,而不是时间问题。

但对每个循环中的内存(memory_get_usage())的测试表明,第一个循环的内存是1.1 MB,而第34个循环的内存是1.2 MB

问题

请在下面找到我的代码,但我想它应该是可以的。有谁知道是什么导致了这个问题吗?非常感谢!

myMailer.class

代码语言:javascript
复制
class myMailer extends PHPMailer {

    public function __construct(?bool $exceptions = true) {
        $config = parse_ini_file('../../ini/config.ini', true);

        parent::__construct($exceptions);

        try {
            // Language of Errors
            $this->setLanguage('en', dirname(__FILE__) . '/../external/PHPMailer/language/');

            // Server settings
            $this->SMTPDebug  = 0;                                  // Enable verbose debug output
            $this->isSMTP();                                        // Set mailer to use SMTP
            $this->SMTPAuth   = true;                               // Enable SMTP authentication
            $this->SMTPSecure = 'ssl';                              // Enable TLS encryption, `ssl` also accepted
            $this->Port       = 465;                                // TCP port to connect to
            $this->Host       = $config['smtp_server']['host'];     // SMTP server
            $this->Username   = $config['smtp_server']['username']; // SMTP username
            $this->Password   = $config['smtp_server']['password']; // SMTP password
            $this->CharSet    ='UTF-8';                             // Set Character Set
            $this->isHTML(true);                                    // Set email format to HTML
            $this->setFrom("office@superman.com", "superman OFFICE");

        } catch (Exception $e) {
            // echo 'Message could not be sent. Mailer Error: ', $mail->ErrorInfo;
            trigger_error("myMailer(): " . $this->ErrorInfo,E_USER_ERROR);
        }
    }

    public function setBody(string $salutation, string $receiver, string $message) : void {
        // Linebreak to <BR>
        $message = nl2br($message);

        // Create Body
        $body = file_get_contents('../../ini/email_template.html');
        $body = str_replace("{Receiver}",       $receiver,                  $body);
        $body = str_replace("{Salutation}",     $salutation,                $body);
        $body = str_replace("{Message}",        $message,                   $body);

        $this->Body = $body;
    }
}

send_emails.php

代码语言:javascript
复制
<?php
$groupID     = $_POST['id'];
$subject     = $_POST['Subject'];
$message     = $_POST['Message'];
$attachments = (key_exists('Files', $_POST)) ? $_POST['Files'] : array();

$group = new Group($groupID);

// Prepare and get HTML
$htmlGenerator  = HtmlGenerator::getInstance();
$htmlGenerator->setTitle("sending emails");
$header = $htmlGenerator->getWebbaseHtmlHeader();
$footer = $htmlGenerator->getWebbaseHtmlFooter();

echo $header;

?>
    <div class="container">
        <h1>Emailing</h1>
        <h3>Group: <?php echo $group->getTitle(); ?></h3>
        <h4>Number of members: <?php echo $group->getNumberOfMembers(); ?></h4>
        <?php

            $strScreenOutput = "
                <table class='table table-sm table-hover table-responsive-md'>
                    <thead class='thead-dark'>
                        <th scope='col'>Nr.</th>
                        <th scope='col'>Date</th>
                        <th scope='col'>Company</th>
                        <th scope='col'>Lastname</th>
                        <th scope='col'>Firstname</th>
                        <th scope='col'>Email</th>
                        <th scope='col'>Newsletter</th>
                        <th scope='col'>Result</th>
                    </thead>
                    <tbody>";

            $protocol = $strScreenOutput;

            echo $strScreenOutput;

            $i = 0;
            $members  = Contact::getAllOfGroup($groupID);
            foreach ($members as $contact) {
                $i++;
                $datRun = date('d.m.Y (H:i:s)');

                if ($contact->getNewsletter() === false) {
                    $result = "no sub.";
                } elseif ($contact->getEmail() === "" || $contact->getEmail() === null) {
                    $result = "no email";
                } else {
                    $return = $contact->sendEmail($subject, $message, $attachments);
                    $result = ($return===true) ? "ok" : $return;
                }

                // create feedback for browser
                $strScreenOutput  = "<tr>";
                $strScreenOutput .= "<th scope='row'>".str_pad($i, 4 ,'0', STR_PAD_LEFT)."</th>";
                $strScreenOutput .= "<td>{$datRun}</td>";
                $strScreenOutput .= "<td>{$contact->getCompany()}</td>";
                $strScreenOutput .= "<td>{$contact->getLastName()}</td>";
                $strScreenOutput .= "<td>{$contact->getFirstName()}</td>";
                $strScreenOutput .= "<td>{$contact->getEmail()}</td>";
                $strScreenOutput .= "<td>".(($contact->getNewsletter()) ? "yes" : "no")."</td>";
                $strScreenOutput .= "<td>{$result}</td>";
                $strScreenOutput .= "</tr>";
                echo str_pad($strScreenOutput,4096)."\n"; // Add some additional blanks to enable flushing (as some browsers suppress flushing)

                // create internal protocol
                $protocol .= $strScreenOutput . "\n";

                // Send to browser
                flush();
                ob_flush();

                // add some execution time
                set_time_limit(30);
            }

            $strScreenOutput = "</tbody>
                            </table>";
            $protocol .= $strScreenOutput;
            echo $strScreenOutput;
        ?>

        <h3>Emails successfully transmitted.</h3>
    </div>

<?php

    // send protocols
    $protocol = "<h3>Group: {$group->getTitle()}</h3>".$protocol;
    $protocol = "<div style='margin-top: 30px'>$protocol</div>";

    $internal = new Contact(1);
    $internal->sendEmail("PROTOCOL: ".$subject, $message . $protocol, $attachments);

echo $footer;

Contact::sendEmail()

代码语言:javascript
复制
public  function sendEmail(string $subject, string $message, array $attachments = array()) {
    $mail = new myMailer();

    if ( is_null($this->getEmail() || $this->getEmail() == "") ) {
        return false;

    } else {
        try {
            // Compose Email
            $mail->addAddress($this->getEmail(), $this->getFirstName() . " " . $this->getLastName());
            $mail->Subject = $subject;
            $mail->setBody($this->getSalutationText(), $this->getAddress(), $message);

            foreach ($attachments as $file) {
                $uploadPath  = $_SERVER['DOCUMENT_ROOT'] . "/../../files/email_attachments/";
                $file_url = $uploadPath.$file;

                if (! is_dir($uploadPath))    { die("Folder \"$uploadPath\" does not exist.");}
                if (! file_exists($file_url)) { die("File \"$file_url\" does not exist."); }

                $mail->addAttachment($file_url);
            }

            $return = $mail->send();

            // clean up
            $mail->clearAddresses();
            $mail->clearAttachments();

        } catch (Exception $error) {
            $return = $error->getMessage();
        }

        return $return;
    }

    unset($mail);

}
EN

回答 1

Stack Overflow用户

发布于 2019-05-20 04:21:05

这听起来确实像是内存问题-在发送大型附件时,PHPMailer在内存上的效率不是很高-尝试在循环中回显从memory_get_usage()获得的内容,以确认内存消耗。

不过,通常情况下,您的发送效率非常低,因为您要创建一个新的PHPMailer实例,重新处理相同的附件,并为每封邮件打开一个新的SMTP连接,所有这些操作只需要做一次。有关如何更有效地发送,请查看the mailing list example provided with PHPMailerthe wiki doc on sending to lists

更高效地重用实例和连接可能会降低您的总体内存需求。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56210009

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档