Проблема
У меня есть скрипт для отправки информационных бюллетеней моим контактам.Скрипт работает нормально, если у меня нет вложения (доказано 2000 писем).
Теперь, если я использую вложения, скрипт тоже работает отлично.Но только отправив около 30 электронных писем.
Test-Setup
- группа из 100 электронных писем, которые необходимо выполнить (цикл).
- вложения: 2 файла (всего 4,6 МБ) -> сценарий завершается (но без сообщения об ошибке) через 50 секунд и отправлено 34 электронных письма.(~ 156 МБ).
Варианты тестирования
- изменение в php.ini
memory_limit
со 100M до 500M -> не имеетэффект.Все еще ошибка после 34 электронных писем. - вставка
sleep(5)
после каждого цикла -> не имеет никакого эффекта.Все еще ошибка после 34 писем. - без вложений: все 100 писем отправлены (около 30 секунд).
- без вложений на 2000 писем: все 2000 писем отправлены (около 6 минут).
- без эффекта изменения
max_execution_time
в php.ini.
Допущения
Из-за ожидаемого поведенияпроблема, а не проблема времени.
Но проверка памяти (memory_get_usage()
) в каждом цикле показала, что память первого цикла равна 1.1 MB
, а 34-го цикла 1.2 MB
.
Вопрос
Пожалуйста, найдите мой код ниже, но я думаю, что все будет в порядке.У кого-нибудь есть идея, что является причиной проблемы?Большое спасибо!
myMailer.class
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
<?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;
Контактное лицо:: sendEmail ()
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);
}