Обычно я делал бы это со своего рода семафор подсчета :
, Если Вы не хотите добираться, который усложнил, Вы могли просто добавить сон () вызов в Вашем цикле с условием продолжения с тривиально маленьким временем сна. Это заставит Ваше сообщение, обрабатывающее поток уступать, это - процессорное время к другим потокам. ЦП больше не будет привязан в 100%, но это все еще довольно расточительно.
Вот как это сделать. Вы говорите браузеру прочитать первые N символов вывода, а затем закрыть соединение, в то время как ваш скрипт продолжает работать, пока не будет завершено.
<?php
ob_end_clean();
header("Connection: close");
ignore_user_abort(); // optional
ob_start();
echo ('Text the user will see');
$size = ob_get_length();
header("Content-Length: $size");
ob_end_flush(); // Will not work
flush(); // Unless both are called !
// At this point, the browser has closed connection to the web server
// Do processing here
include('other_script.php');
echo('Text user will never see');
?>
Вы можете эффективно добиться этого, разветвив и затем вызвав include
или require
.
parent.php:
<?php
$pid = pcntl_fork();
if ($pid == -1) {
die("couldn't fork");
} else if ($pid) { // parent script
echo "Parent waiting at " . date("H:i:s") . "\n";
pcntl_wait($status);
echo "Parent done at " . date("H:i:s") . "\n";
} else {
// child script
echo "Sleeper started at " . date("H:i:s") . "\n";
include('sleeper.php');
echo "Sleeper done at " . date("H:i:s") . "\n";
}
?>
sleeper.php:
<?php
sleep(3);
?>
Вывод:
$ php parent.php Sleeper started at 01:22:02 Parent waiting at 01:22:02 Sleeper done at 01:22:05 Parent done at 01:22:05
Однако разветвление по своей сути не допускает какого-либо взаимодействия между процессами, поэтому вам нужно будет найти другой способ сообщить родителю, что дочерний элемент достиг определенной строки, как вы задали в вопросе.
Вот снимок в темноте: вы можете попробовать использовать функции выполнения ОС php с и
.
exec("./somescript.php &");
Кроме того, если это не сработает, вы можете попробовать
exec("nohup ./somescript.php &");
Будет ли pcntl_fork ()
делать что-то похожее на то, что вы в конечном итоге пытаетесь достичь? http://www.php.net/manual/en/function.pcntl-fork.php
Если вы не хотите создавать расширение pcntl, хорошей альтернативой является использование proc_open ().
http://www.php.net/manual/en/ function.proc-open.php
Используйте его вместе с stream_select (), чтобы ваш PHP-процесс мог спать, пока что-то не произойдет с дочерним процессом, который вы создали.
Это эффективно создаст процесс в фоновом режиме, не блокируя родительский PHP-процесс. PHP может читать и писать в STDIN, STDOUT, STDERR.
Для полной загрузки браузера (остановки индикатора загрузки) вы можете использовать то, что упомянул Милан Бабушков.
Ключом к тому, чтобы заставить браузер считать HTTP-запрос завершенным, является отправка ему длины содержимого. Для этого вы можете начать буферизацию запроса, а затем сбросить его после отправки заголовка Content-Length.
например:
<?php
ob_start();
// render the HTML page and/or process stuff
header('Content-Length: '.ob_get_length());
ob_flush();
flush();
// can do more processing
?>