【问题标题】:Execute script in background在后台执行脚本
【发布时间】:2021-08-27 13:40:57
【问题描述】:

我一直在尝试处理的代码有一个小问题。我试图在我的项目中的不同时间使用 php 发送邮件,其中大多数是用户触发的。由于有不同的邮寄点和页面,我创建了一个邮寄脚本,我将所有邮寄请求发送到其中(这样,所有电子邮件都从一个页面发送)。

例如,注册后,注册脚本中的验证码会发送到邮件脚本,该邮件脚本会向用户发送验证电子邮件。然后注册脚本在重定向到下一页之前等待来自邮件脚本的响应。但是由于很多因素,邮件脚本需要一些时间来加载。

我不希望用户遇到这种延迟,因此我一直在寻找一种在用户被重定向到另一个页面而不是等待来自的响应时在后台将数据发送到邮件脚本的方法邮件脚本。

我尝试使用 AJAX 直接从前端发送数据,但我使用了验证过程,其中某些值从数据库进行身份验证,因此我必须从注册脚本发送。我一直在寻找 AJAX 的 php 等效项,在用户被重定向之前,我不必等待邮件脚本的响应。我尝试过 CURL,但不知何故,它仍然在等待响应。

这是我的 cURL 代码:

$url = "https://requiredurl";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPGET, 1);
$data = curl_exec($ch);
curl_close($ch);
header("location: returnurl");      
exit();

我希望它在执行 cURL 命令后立即重定向到重定向 url 而无需等待响应。

我需要任何其他 php 方法的帮助才能使它工作。提前致谢。

【问题讨论】:

  • 我建议使用异步工具,例如 Symfony Messenger component
  • 尝试使用 cronjob 或使用主管之类的工具。
  • 听起来你可以在市场上学习如何使用队列,例如使用 redis 或 beanstalkd。将请求从一端推送到队列中,并在它们可用时将其拉出。这意味着您的脚本不必等待结果。等待电子邮件发送通常表明您没有使用 SMTP 到 localhost,这是迄今为止最快的方式。

标签: php mysql ajax curl phpmailer


【解决方案1】:

如果您确实通过注册脚本收集用户信息,我认为使用 GET 方法并不安全。你应该使用 POST 方法:

$postData = array(
    "data1" => "Test Data1",
    "data2" => "Test Data2",
    "data3" => "Test Data3"
);

$url = "https://requiredurl";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_exec($ch);

但是,如果您决定继续,可能对您有用的方法是删除 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);,或者您可以轻松地将其注释掉。这样,命令会运行,但 cURL 不会发回或显示任何响应。

这是不可取的,因为您不知道命令是否运行,但它至少可以解决您的问题。

另一种方法

将添加此代码:

// don't let user kill the script by hitting the stop button
ignore_user_abort(true);

// don't let the script time out
set_time_limit(0);

// start output buffering
ob_start();  

// If you need to return data to the browser, run that code
// here. For example, you can process the credit card and
// then tell the user that their account has been approved. 

usleep(1500000); // delay before redirecting user

// now force PHP to output to the browser...
$size = ob_get_length();
header("Content-Length: $size");
header('Connection: close');
ob_end_flush();
ob_flush();
flush(); 
// everything after this will be executed in the background.
// the user can leave the page, hit the stop button, whatever.
usleep(2000000); // delay before executing background code

在邮件功能行之前。

这样,当用户被重定向到另一个页面时,代码将在后台执行。

希望对你有帮助

【讨论】:

    【解决方案2】:

    您可以使用屏幕命令 使用sudo apt install screen 安装它 之后运行screen 并按空格并执行您的脚本,现在您可以关闭终端了。 如果您需要返回或查看您的屏幕,请运行screen -ls,就像:

    $ screen -ls
    There is a screen on:
            17216.pts-2.localhost   (Detached)
    1 Socket in /path/to/home/.screen.
    

    要恢复屏幕,例如运行screen -r 17216

    【讨论】:

      猜你喜欢
      • 2015-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-30
      • 2011-01-01
      • 2016-06-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多