Может ли 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

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



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. Это должно сделать то, что вы ищете.