当 curl return 200 时停止 foreach 循环

Stop foreach loop when curl return 200

我尝试与我的 Proxmox 集群通信,该集群包含来自 API 的 3 个服务器。目标是在发生故障时至少连接到这些服务器中的 1 个,然后执行其他代码(此处不可见)。

使用下面的代码,我使用 "foreach" 一对一地连接到​​这些服务器,我希望当一个服务器 return 来自 Curl 的“200”时这个循环停止(这样我可以继续这个在线服务器)。为了测试,我停止了第一台服务器并让其他 2 台服务器在线,但 "foreach" 循环保持连接第三台服务器。

有什么想法吗?谢谢你,对不起我的英语。

<?php

$datas = array(
    array(
        "apiurl" => "192.168.1.34:8006",
        "node" => "pve1",
        "user" => "root",
        "userpass" => "pass",
    ),
    array(
        "apiurl" => "192.168.1.35:8006",
        "node" => "pve2",
        "user" => "root",
        "userpass" => "pass",
    ),
    array(
        "apiurl" => "192.168.1.36:8006",
        "node" => "pve3",
        "user" => "root",
        "userpass" => "pass",
    )
);

do {
    foreach ($datas as $data) {
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, 'https://'.$data['apiurl'].'/api2/json/access/ticket');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, 'username='.$data['user'].'@pam&password='.$data['userpass']);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($ch, CURLOPT_TIMEOUT, 2);

        $headers = array();
        $headers[] = 'Content-Type: application/x-www-form-urlencoded';

        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

        $result = curl_exec($ch);

        if (curl_errno($ch)) {
            echo 'Server ' .$data['node']. ' is not reachable (error : ' .curl_error($ch). ')<br>';
        }
        else {
            $myArray = json_decode($result, true);
            $cookie = $myArray['data']['ticket'];
            $info = curl_getinfo($ch);
            echo "Server " .$data['node']. " is reachable (code is : " .$info['http_code']. ")<br>";
        }
    curl_close($ch);
    }
} while ($info['http_code'] !== 200);
?>

您可以通过给 break 一个参数来跳出外层循环。 break 2表示跳出第二个包含循环。

while (true) {
    foreach ($datas as $data) {
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, 'https://'.$data['apiurl'].'/api2/json/access/ticket');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, 'username='.$data['user'].'@pam&password='.$data['userpass']);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($ch, CURLOPT_TIMEOUT, 2);

        $headers = array();
        $headers[] = 'Content-Type: application/x-www-form-urlencoded';

        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

        $result = curl_exec($ch);

        if (curl_errno($ch)) {
            echo 'Server ' .$data['node']. ' is not reachable (error : ' .curl_error($ch). ')<br>';
        }
        else {
            $myArray = json_decode($result, true);
            $cookie = $myArray['data']['ticket'];
            $info = curl_getinfo($ch);
            echo "Server " .$data['node']. " is reachable (code is : " .$info['http_code']. ")<br>";
            if ($info['http_code'] == 200) {
                break 2;
            }
        }
        curl_close($ch);
    }
}

这里是一个无限循环,因为正如您所说,您已经知道阵列中的最后 2 台服务器不会成功响应,但是您的 foreach 循环将尝试所有 3 台服务器,无论成功与否失败。因此,当您到达 foreach 循环的第 3 次迭代时,您会得到一个失败的响应,然后 然后 您到达 while 循环的末尾,这决定了条件仍然是 true 并继续。为防止这种情况,一旦确定成功,只需从 foreach 循环中中断即可。因为只有然后才会while循环的条件变成false。如果愿意,您也可以跳出两个循环(使用 break 2)。任何一个都是正确的。唯一的区别是,无论成功还是失败,您是否希望外部 (while) 循环中的任何剩余逻辑都发生。

foreach ($datas as $data) {
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, 'https://'.$data['apiurl'].'/api2/json/access/ticket');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, 'username='.$data['user'].'@pam&password='.$data['userpass']);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($ch, CURLOPT_TIMEOUT, 2);

        $headers = array();
        $headers[] = 'Content-Type: application/x-www-form-urlencoded';

        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

        $result = curl_exec($ch);

        if (curl_errno($ch)) {
            echo 'Server ' .$data['node']. ' is not reachable (error : ' .curl_error($ch). ')<br>';
        }
        else {
            $myArray = json_decode($result, true);
            $cookie = $myArray['data']['ticket'];
            $info = curl_getinfo($ch);
            echo "Server " .$data['node']. " is reachable (code is : " .$info['http_code']. ")<br>";
            if (!empty($info['http_code']) && $info['http_code'] == 200) {
                break; // break out of either or both loops since we got a valid response
            }
        }
    curl_close($ch);
}