我怎样才能让php函数在后台的while循环中继续运行?

问题描述 投票:0回答:1

如何使 otpChange() 函数在后台运行并立即返回响应,并且基本上不等待 otpChange() 函数结束(在后台运行)。我想到在后台运行它或使用 return;并且仍然以某种方式运行,但如果您有任何解决方案,请写信。

<?php
include 'db.php';
// Check if the request method is POST
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    // Check if action is provided
    if (isset($_POST["action"])) {
        // Handle the action
        handleAction($_POST["action"]);
    } else {
        // Return an error response if action is not provided
        $response = array(
            "re" => 1,
            "re_err" => "Action not provided",
            "re_err_num" => 1003
        );
        header('Content-Type: application/json');
        echo json_encode($response);
    }
} else {
    // Handle non-POST requests
    http_response_code(405); // Method Not Allowed
    echo "Method Not Allowed";
}

$phone = '';
$otp = '';
function login($conn) {
    //return array("message" => "Function 1 called");
    global $phone, $otp;
    $phone = $_POST['phone'];
    $sql = "";
    
    $result = $conn->query($sql);
    $otp = rand(100000, 999999);
    // return;
    //$response['re_data'][] = "No specific action performed";
    return;
}
function otpChange($conn, $phone, $otp) {
    $counter = 60;
    // $conn->query($setOtpExpiry);
    while ($counter >= 0) {
        $update_otp = "";
        $conn->query($update_otp);
        sleep(1);
        $counter--;
    }
    $response['re_data'][] = "No specific action performed";
    // return;
}

// login_check();
function handleAction($action) {
    // Initialize response variables
    $response = array(
        "re" => 0,
        "re_data" => array(),
        "re_err" => "",
        "re_err_num" => 0
    );

    // Check for specific actions
    if ($action == 'login') {
        global $conn, $phone, $otp;
        login($conn);
        $response['re_data'][] = "Login Action";
        otpChange($conn, $phone, $otp); //i dont want that loop to interfere with the login action, i want that when i call the login action it will Immediately $response['re_data'][] = "Login Action"; and not wait for the loop
    } elseif ($action == 'login_check') {
        // login_check();
    } else {
        // Implement your condition here
        // For example, check if any data has changed
        $dataChanged = false; // Assume no change initially

        // If data has changed, modify the response accordingly
        if ($dataChanged) {
            // Respond with custom data
            $response["re"] = 1;
            $response["re_err"] = "Data has changed";
            $response["re_err_num"] = 1001;
        } else {
            // Respond with default data
            $response['re_data'][] = "No specific action performed";
        }
    }

    // Return the response as JSON with ordered keys
    header('Content-Type: application/json');
    echo json_encode($response);
}
?>
php loops background-process
1个回答
0
投票

PHP 的同步特性和 Web 服务器处理请求的方式使得执行 otpChange() 等长时间运行的任务变得困难。

但是你可以通过以下方式实现它 PHP-FPM(FastCGI 完成请求) https://www.php.net/manual/en/install.fpm.php

您可以使用fastcgi_finish_request()将响应发送给客户端,然后继续在后台执行脚本。

所以你可以做这样的事情

function handleAction($action) {
    global $conn, $phone, $otp;

    if ($action == 'login') {
        login($conn);
        $response['re_data'][] = "Login Action";

        // Send the response to the client
        header('Content-Type: application/json');
        echo json_encode($response);

        // End the request and flush all response data to the client
        if (function_exists('fastcgi_finish_request')) {
            fastcgi_finish_request();
        }

        // Continue with the background process
        otpChange($conn, $phone, $otp);
    }
    
}

唯一的问题是 fastcgi_finish_request() 特定于 PHP-FPM,不能与 Apache 上的 mod_php 等其他服务器 API 一起使用。

如果您不满意,那么您可以尝试 使用队列

  • 登录操作时将任务(带有必要的数据)推送到队列 发生。
  • 使用工作脚本处理队列(通过 cron 或 demo,就像您 想要)

如果您需要任何设置队列的说明,请在评论中告诉我,我将尽力提供一些据我所知的步骤。

希望有帮助

© www.soinside.com 2019 - 2024. All rights reserved.