Неблокирующая альтернатива fsockopen в PHP? - PullRequest
0 голосов
/ 10 июня 2019

Я прочитал много ответов, но не нашел четкого объяснения.Я пытаюсь сделать инструмент проверки открытого порта в PHP.

При использовании fsockopen сервер перестает работать, когда он проверяет каждый порт, поэтому я не могу использовать этот метод для проверки состояния портов.

Есть ли эффективный способ сделать то же самое, но неблокирующим или асинхронным способом?

Это мой (неэффективный) код:

        $resultList = [];
        foreach ($list as $key => $value) {
             $object = new stdClass();
             $object->id = $value["id"];

            if (fsockopen($value["ip"], $value["port"])) {
                 $object->status = true;
            } else {
                $object->status = false;
            }
            array_push($resultList,$object);
        }

1 Ответ

0 голосов
/ 10 июня 2019

PHP-скрипт всегда синхронен - ​​вы вызываете функцию, ждете, пока она завершится, прежде чем ваш скрипт будет запущен, однако вы можете использовать PHP для запуска второго PHP-скрипта в качестве нового процесса с помощью следующей обобщенной команды:

shell_exec('/usr/bin/php -f /path/to/script.php &> /dev/null &');

Теперь это не очень помогает вашей проблеме. Я просто включил ее, чтобы ответить на точные слова вашего вопроса - вы не можете заставить этот второй скрипт PHP взаимодействовать с первым каким-либо образом без участия AJAX, после чего вы можете а также просто AJAX целиком.


Чтобы попытаться ответить на дух вашего вопроса, я хотел бы предложить другой подход:

У вас есть родительская страница:

<?php

$hostname = '192.168.0.1';

?>
<h1>Ports for server <?php echo $hostname; ?>:</h1>
<iframe src="/path/to/my/post-scanner-script.php?hostname=<?php echo urlencode($hostname); ?>"></iframe>

Затем ваша дочерняя страница последовательно сканирует каждый порт, и после завершения сканирования этот порт использует flush()

<?php

// Stuff here to interpret $_GET['hostname'];

foreach ($list as $key => $value) {
    $status = !!fsockopen($value["ip"], $value["port"]);
    echo "<div>{$value['id']}: " . ($status ? 'OPEN' : 'CLOSED') . "</div>";
    flush();
}

Что сделает flush(), так это немедленно отправит весь обработанный вывод на клиентский компьютер (он не будет отправлять одно и то же содержимое дважды), так что вы получите медленно появляющийся список каждого порта и его состояния, появляющийся, как только так как ваш скрипт знает состояние порта.

Это обеспечивает некоторую немедленную обратную связь с конечным пользователем, а также менее разочаровывающее ожидание (это намного более терпимо, когда вы действительно можете увидеть достигнутый прогресс).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...