【问题标题】:PHP mail script using up huge amounts of resourcesPHP邮件脚本占用大量资源
【发布时间】:2013-08-07 18:06:45
【问题描述】:

我需要一次向注册用户发送几百封电子邮件,但我遇到了问题。只要它正在发送电子邮件,我使用的 PHP 脚本(并且之前在不同的托管服务上使用过,没有问题)就会滞后于整个服务器(顺便说一下,它有 8GB 内存)。

现在,我与托管支持人员交谈,询问他们的邮件服务器是否有问题,或者是否有一些外发邮件限制或其他什么,他们说没有。事实上,他们坚决声称这是一个编码问题。我对此表示高度怀疑,但该脚本可能自几个月前上次使用以来略有改变,因此我在下面分享了该脚本,我将发送的典型电子邮件位于 $content 变量中。

问题是,有人能看出这段代码疯狂消耗资源的原因吗?

我检查了 MySQL 日志,查询本身(从数据库获取电子邮件)并不慢。所以这是邮件本身。

PHP mail_sender 文件:

$content="<p style='line-height:20px;margin:10px 0;'>Hello,</p>

<p style='line-height:20px;margin:10px 0;'>This is an email to notify you etc etc.</p>

<p style='line-height:20px;margin:10px 0;'>This is line 2 of the email, it's usually not much longer than this example.</p>

<p style='line-height:20px;margin:10px 0;'>Regards,<br/>Site Name staff</p>";

$result=mysql_query("select email from members where tipster_by_email='1' ") or die(mysql_error());
while($row=mysql_fetch_assoc($result)){
    sendToUser($row['email'],$admin_email,"Email Title",$content);
}

这是函数本身:

//generic HTML-formatted e-mail sender
function sendToUser($email,$admin_email,$subject,$content){

//define the receiver of the email
$to = $email;
//create a boundary string. It must be unique
//so we use the MD5 algorithm to generate a random hash
$random_hash = md5(date('r', time()));
//define the headers we want passed. Note that they are separated with \r\n
$headers="From: Site Name <$admin_email>";
$headers.="\r\nReply-To: $admin_email";
//add boundary string and mime type specification
$headers .= "\r\nMIME-Version: 1.0"; 
$headers .= "\r\nContent-Type: text/html; ";
//define the body of the message.
ob_start(); //Turn on output buffering 
?>

<div style="width:730px;text-align:justify;margin-bottom:25px;">

<?php echo stripslashes($content); ?>

<div style='width:100%;height:1px;background:#ccc;margin:10px 0;'></div>

<div style='width:100%;color:#333;font-size:12px;'>
    <p style='line-height:12px;margin-top:10px;'>Site Name is owned by Company Name</p>
    <p style='line-height:12px;margin-top:10px;'>All rights reserved.</p>
    <p style='line-height:12px;margin-top:10px;'><a style='color:blue;' href='facebookurl'>Like us on Facebook</a> or <a style='color:#b04141;' href='twitterurl'>follow us on Twitter</a></p>
</div>

</div>

<?php
//copy current buffer contents into $message variable and delete current output buffer
$message = ob_get_clean();
//send the email
mail( $to, $subject, $message, $headers );
}

是否有任何理由会耗尽资源或执行缓慢?服务器速度非常快,其他都没有问题。

php.ini 中的邮件设置:

Mail    SMTP    Used under Windows only: host name or IP address of the SMTP server PHP should use for mail sent with the mail() function.  [strikethrough]localhost[/strikethrough] **DEFAULT**, Click to Edit
Mail    sendmail_from       [strikethrough]me@localhost.com[/strikethrough] **DEFAULT**, Click to Edit
Mail    sendmail_path       /usr/sbin/sendmail -t -i
Mail    smtp_port       25

【问题讨论】:

  • 您是否向每个用户发送相同的内容?如果是这样,您只需发送一封电子邮件,并将每个用户添加为密件抄送地址。
  • 有时,是的。但通常在电子邮件的第 2 行中有一个“取消订阅”链接,每个用户都是独一无二的,所以我不能这样做。但是谢谢你的想法,我不知道。
  • 这个查询返回多少条记录? :select email from members where tipster_by_email='1'
  • 几百。但是即使我将查询限制为 50 个结果,脚本也会使整个服务器滞后 20 秒。
  • 您的 php.ini 文件中的邮件设置是什么?

标签: php email


【解决方案1】:

@Pitchinnate 提到 ob_*() 函数并不是性能最好的。我不能明确地对此发表评论,但这听起来似乎是合理的。更好的选择是替换:

ob_start(); //Turn on output buffering 
?>

<!-- HTML -->

<?php
//copy current buffer contents into $message variable and delete current output buffer
$message = ob_get_clean();

与:

$message = <<<_EOI_

<!-- HTML -->

_EOI_;

这称为'HEREDOC' syntax,您可以像使用双引号字符串一样使用$variables

除此之外,我真的看不到任何会导致服务器上的 MTA 出现问题的东西。如果您删除输出缓冲位并且脚本仍然会导致数百条消息出现问题,我不得不说邮件服务器配置不是最佳的。例如。它们允许过多的 sendmail 守护进程在后台启动,并且正在消耗服务器内存。

此外,在所有自动邮件中,您应该始终包含某种取消订阅机制,无论是链接还是有关如何选择退出的说明。那,并确保它及时工作。 :P

【讨论】:

  • 我有一个取消订阅机制,我只是没有在这里展示它,因为有或没有它的滞后是一样的:) 我会尝试不带 ob 部分,但我认为这只是一个问题的托管支持人员将他们的工作倾销给我。
猜你喜欢
  • 2016-02-21
  • 1970-01-01
  • 1970-01-01
  • 2015-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
相关资源
最近更新 更多