作为守护进程运行php脚本

作为守护进程运行php脚本,php,daemon,Php,Daemon,我有一个通过API提供VPS的程序。脚本的核心部分将继续命中API(每5秒,15次),直到API吐回IP地址。执行大约需要30秒 代码中没有错误,程序以97%的可靠性执行其功能 但是,如果最终用户不耐烦并点击离开,脚本将过早结束,我的系统将崩溃 有没有一种方法可以将php脚本的一部分作为deamon在后台运行?这样,如果用户在意外情况下点击,流程仍然运行吗? 还是其他方法 脚本: <?php session_start(); require_once('../pages/mail/conf

我有一个通过API提供VPS的程序。脚本的核心部分将继续命中API(每5秒,15次),直到API吐回IP地址。执行大约需要30秒

代码中没有错误,程序以97%的可靠性执行其功能

但是,如果最终用户不耐烦并点击离开,脚本将过早结束,我的系统将崩溃

有没有一种方法可以将php脚本的一部分作为deamon在后台运行?这样,如果用户在意外情况下点击,流程仍然运行吗? 还是其他方法

脚本:

<?php
session_start();
require_once('../pages/mail/config.php');
DCID=1&VPSPLANID=1&SNAPSHOTID=df55172be2c87');

$cust_label = $_POST['sname'];;


//here we provision the server with vultr
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL,"https://api.vultr.com/v1/server/create?api_key=nnnnnn1eSKIee");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,
        "DCID=19&VPSPLANID=31&OSID=164&SNAPSHOTID=c24554280420a&label=".$cust_label."&enable_ipv6=yes");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec ($ch);
curl_close ($ch);

//recovering the IP takes a little while
sleep(15);
echo 'first we get your IPv4 address';
//now we need the ip address
function getlist(){
        $list_output = file_get_contents('https://api.vultr.com/v1/server/list?api_key=ddddddIOCe');
        return $list_output;
}


$output = getlist();
$decoded = json_decode($output, true);
foreach($decoded as $value) {
        $ip = $value['main_ip'];
        $label = $value['label'];
        $subid = $value['SUBID'];
        //if the label matched the current on it session, get that data
        if($label === $cust_label) {
                $ipr = $ip;
        }
}
//this one will get it
for ($x = 0; $x <= 15; $x++){
        if($ipr === '0'){
                sleep(5);
                $output2 = getlist();
                $decoded2 = json_decode($output2, true);
                foreach($decoded2 as $value2) {
                        $ipd = $value2['main_ip'];
                        $label = $value2['label'];
                        $subid = $value['SUBID'];
                        if($label === $cust_label){
                                $ipr = $ipd;
                                break;
                        }
                }
        }
}
//no IPv4 is bad. error out and send a message to admin
if($ipr === '0'){
        echo 'Something bad happened, we did not get and IP address back. A message has been sent to admin to review your account';
        echo '<a id="ticket" target="_self" href="support/viewforum.php?f=4">Support Portal</a>';
        echo '<a id="home" target="_self" href="index.php?p=home"><i>Home</i></a>';

        $to      = 'postmaster@ex-ler.com';
        $subject = 'New entry failure';
        $message = 'VPS initialization error occured';
        $headers = 'From: postmaster@ex-ler.com' . "\r\n" .
                'Reply-To: webmaster@ex-ler.com' . "\r\n" .
                'X-Mailer: PHP/' . phpversion();

        mail($to, $subject, $message, $headers);
        exit();
}

//let's try and get the IPv6
$output3 = getlist();

$decoded3 = json_decode($output3, true);
foreach($decoded3 as $value3) {
        $ipv6 = $value['v6_main_ip'];
        $label = $value['label'];
        $subid = $value['SUBID'];
        if($label === $cust_label) {
                $ipr6 = $ipv6;
        }
}
$count = 0;
for ($x = 0; $x <= 25; $x++){
        if(empty($ipr6)){
                sleep(5);
                echo 'here '.$x;
                $output4 = getlist();
                $decoded4 = json_decode($output4, true);
                foreach($decoded4 as $value4) {
                        $ipdv6 = $value4['v6_main_ip'];
                        $label = $value4['label'];
                        $subid = $value['SUBID'];
                        if($label === $cust_label){
                                $ipr6 = $ipdv6;
                                break;
                        }
                }
        }
}
$_SESSION['label'] = $value['label'];
$_SESSION['SUBID'] = $value['SUBID'];
var_dump($_SESSION['SUBID']);

$domain = $_SESSION['DOMAIN'];
//now sink the IPs into the database
$pdo = new PDO(
        'mysql:host=' . DB_HOST . ';dbname=' . DB_DATABASE, DB_USER, DB_PASSWORD
);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
//$sql = 'INSERT into domains(label, ipv4) VALUES (:label, :ipaddress)';
$sql = 'UPDATE domains SET subid = :subid, label = :label, ipv4 = :ipaddress, ipv6 = :ipv6address WHERE domain = :domain';

$statement = $pdo->prepare($sql);
$statement->bindParam(':label', $cust_label, PDO::PARAM_STR, 12);
$statement->bindParam(':ipv6address', $ipr6, PDO::PARAM_STR, 48);
$statement->bindParam(':ipaddress', $ipr, PDO::PARAM_STR, 12);
$statement->bindParam(':domain', $domain, PDO::PARAM_STR, 255);
$statement->bindParam(':subid', $subid, PDO::PARAM_INT, 14);

$result = $statement->execute();



//go to member profile
header("location: ../index.php?p=member-profile");

?>
使用以下命令:

ignore_user_abort(true);
因此,如果用户关闭窗口,PHP脚本将继续运行,直到完成


更多信息

您可以尝试将curl内容拆分为子进程,然后返回父进程。您将使用的命令是pcntl_fork()

下面是一个示例模型,演示了如何做到这一点:只需将curl代码放入子进程块(执行sleep()的位置附近),看看是否满足您的要求:

<?php

// this variable is here to prove that variables set outside of the 
// child process' 'if' block can be accessed
$outsideVariable = "i'm from outside";

// fork starts a copy of this script
$pid = pcntl_fork();

// if the return from pcntl_fork() is -1, things have gone awry
if($pid == -1){
    die("could not spawn child process. do some error handling";
}

// this is the code that gets executed in the original 'parent'
// process. you do html output here so the user doesn't have to 
// wait for the email to be set.
else if($pid == 0){
    print "return to user and stop execution";
    return true;
}

// this is the child process, the copy of the process that is
// spawned seperately. you can do your curl 
// stuff here.
else {
    sleep(10); // simluating execution lag

    // let's write to file to confirm the child process is doing 
    // stuff. we use $outsideVariable  to show that this process
    // can access stuff from the scope of the parent.
    $fp = fopen("/tmp/foo","a");
    fwrite($fp, "chil pid $pid $outsideVariable \n");
}
?>

调查此问题的可能重复。这可能是“美丽的一个”。我正在尝试两个答案。