Может ли PHP-скрипт запустить другой PHP-скрипт и выйти?
как PHP-скрипт может запустить другой PHP-скрипт, а затем выйти, оставив другой скрипт запущенным?
кроме того, есть ли способ для 2-го скрипта сообщить php-скрипту, когда он достигнет определенной строки?
6 ответов
вот как это сделать. Вы говорите браузеру прочитать первые 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
.
родитель.на 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";
}
?>
спальное место.на 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 &");
Would 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
?>
вы можете создать запрос и закрыть соединение сразу после того, как оно будет записано.
проверка кода в http://drupal.org/project/httprl as может сделать это (неблокирующий запрос). Я планирую подтолкнуть этот lib к github, как только я его отполирую; что-то, что можно запустить за пределами drupal. Это должно сделать то, что вы ищете.