【问题标题】:Prevent PHP From Waiting for mail() function防止 PHP 等待 mail() 函数
【发布时间】:2014-03-23 08:49:34
【问题描述】:

在我的 Web 应用程序中,当用户更改其帐户时,我调用 php mail() 函数向该用户发送电子邮件通知。实施此操作后,我发现帐户更改操作需要很长时间(> 20 秒)才能完成。我怀疑这是因为 PHP 等待 mail() 函数发送电子邮件。有没有什么方法可以不用等待就直接调用下一行代码?

谢谢,

保罗

【问题讨论】:

  • 你怀疑?您是否对此进行了基准测试?
  • @MonkeyZeus 如果我注释掉对邮件函数的调用,服务器响应时间不到三秒。如果我允许它调用邮件功能,它需要二十多秒。我认为可以肯定地说邮件功能是罪魁祸首。
  • 出了点问题。 mail() 函数不应该花那么长时间来执行。您可能想弄清楚为什么 mail() 函数需要这么长时间。您的 php.ini 文件应该向您显示 mail() 函数正在使用的底层系统命令。它应该被指定为 sendmail_path。如果您登录服务器并通过指定为 sendmail_path 的命令从命令行发送消息,执行需要大约 10 秒吗?如果是这样,听起来您的服务器上运行的 MTA 可能有问题。
  • 即使是 3 秒,如果没有 mail(),在普通用户眼中也太长了。您的网络中发生了一些事情,导致mail() 速度变慢,因此肯定应该解决这个问题,但您肯定需要考虑优化帐户更新过程。我不知道 PHP 可以以何种方式生成单独的函数而不是等待它们,但在客户端你当然可以实现 AJAX。
  • @MonkeyZeus 延迟三秒的原因是有问题的操作是通过信用卡进行订阅付款。

标签: php email apache2


【解决方案1】:

创建另一个 PHP 脚本(在本示例中,我们将其命名为“mailuser.php”)。在此文件中,您的代码将查找尚未通过电子邮件发送的已激活帐户...然后发送电子邮件。

在您的原始代码中(激活帐户后)调用:

exec("php mailuser.php > /dev/null 2>&1 &");

这应该产生进程,但不等待它返回。

有关更多信息,请参阅以下帖子:php exec command (or similar) to not wait for result & Run PHP Task Asynchronously

您也可以选择在命令行中传递用户 ID,这样 mailuser.php 就不必根据字段/标志来查找用户。

【讨论】:

  • 完美运行,谢谢。我想为任何尝试这样做的人添加,有关如何使用 exec 命令发送参数的更多信息可以在 php 手册中找到:php.net/manual/en/reserved.variables.argv.php
  • 没问题,乐于助人=)
【解决方案2】:

您可以将邮件函数的调用放在一个名为 sendMail.php 的单独 php 文件中,然后使用 (jQuery AJAX)[https://api.jquery.com/jQuery] 将请求发送到该函数.ajax/].

$.ajax({
   type: "POST",
    url: "sendMail.php",
    data: { name: "Foo", email: "foobar@baz.com" }
})
.done(function( msg ) {
    alert( "Email sent: " + msg );
});

【讨论】:

  • 出于安全考虑,我想保留此服务器端。
【解决方案3】:

您可以发送 Ajax 调用以发送邮件,然后出于安全目的,如果邮件未发送,您可以调用数据库查询回滚,这样您的代码将是安全的。

【讨论】:

    【解决方案4】:

    我有同样的问题。编写一个 sendmail.php 程序并用 ajax 调用它。

    <?
    session_start();
    header("Content-Type: text/html; charset=iso-8859-1");
    require_once("libreria/class.phpmailer.php");
    $mail             = new PHPMailer();
    $body="";
    $body.="<body>";
    $body.=$_POST['cbody'];
    $body.="</body>";
    $mail->IsSMTP();
    $mail->SMTPAuth   = true;                  
    //$mail->SMTPDebug  = 2;
    $mail->Host       = "mail.xxx.xxx";
    $mail->Port       = 25;
    $mail->Username   = "usermail@xxx.xxx";  
    $mail->Password   = "xxxxxx";        
    $mail->From       = "usermail@xxx.xxx";
    $mail->FromName   = "xxx";
    $mail->Subject    = $_POST['subject'];
    $mail->WordWrap   = 50;
    $mail->MsgHTML($body);
    $mail->AddAddress($_POST['email'], "User");
    $mail->IsHTML(true);
    $mail->Send();
    ?>
    

    (您可以使用 ajax 调用的响应来管理错误)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-18
      • 2012-04-22
      • 2021-03-09
      • 1970-01-01
      • 2013-07-15
      • 2011-11-24
      • 2022-01-16
      • 2011-12-14
      相关资源
      最近更新 更多