Могу ли я выполнить команду запуска npm через php в фоновом режиме и перейти к следующей строке кода?

На самом деле я работаю над большим проектом, используя php laravel в качестве бэкэнда и реагируя как интерфейс, в котором я бы загружал zip-файл, содержащий проект реагирования, и как только файл будет загружен, он извлек бы файл, выполнил команду npm start, чтобы начать сервер, а затем с помощью кукловода сделайте снимок экрана живого проекта.

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

`<?php
// Execute npm start command in the background

mkdir('hello');
// Start Node.js server in the background using cmd.exe
exec('start /B cmd.exe /C npm start');
mkdir('hi');
?>`

в приведенном выше примере, когда я использую почтальона для запроса на получение, сначала создается «каталог hello», затем запускается сервер реагирования, но «каталог hi» никогда не создавался, пока я не убью процесс узла из диспетчера задач

до сих пор я устал, как и все, и у меня вопрос: невозможно ли сначала создать каталог hello, затем запустить сервер в фоновом режиме и, наконец, создать каталог hi ?? Заранее спасибо.

Вы можете попробовать функцию proc_open, которая поддерживает неблокирующий подпроцесс.

LF-DevJourney 15.04.2024 03:10
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
1
57
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

На компьютере с Linux или Unix вы можете добавить амперсанд (&) после команды, чтобы сделать ее «фоновой». Вместо этой команды

exec('start /B cmd.exe /C npm start');

Добавьте амперсанд:

exec('start /B cmd.exe /C npm start &');

Однако обратите внимание, что команда вернется немедленно, и следующая строка кода может быть выполнена до завершения команды NPM. Возможно, вам придется добавить какой-то цикл, чтобы проверить, завершился ли он каким-либо образом:

while (!npm_has_finished()) // you'd need to write this function
{
  usleep(100000); // sleep for 100 milliseconds
}

сработал следующий скрипт:

<?php
// Function to check if a process is running on a given port
function isProcessRunning($port) {
    $output = shell_exec("netstat -ano | findstr LISTENING | findstr :$port");
    return !empty($output);
}

// Function to kill a process running on a given port
function killProcess($port) {
    $output = shell_exec("netstat -ano | findstr LISTENING | findstr :$port");
    $lines = explode("\n", $output);
    foreach ($lines as $line) {
        if (preg_match('/\s+\d+\s+TCP\s+\d+\.\d+\.\d+\.\d+:' . $port . '\s+\d+\.\d+\.\d+\.\d+:0\s+LISTENING\s+(\d+)/', $line, $matches)) {
            $pid = trim($matches[1]);
            exec("taskkill /F /PID $pid");
            return true;
        }
    }
    return false;
}

// Execute mkdir command for hello directory
$resultHello = mkdir('hello');

// Execute npm start command in the background
$command = 'start /B cmd /c "npm start"';
exec($command);

// Wait for the React server to start (up to 60 seconds)
$max_attempts = 12; // Total attempts (each attempt waits for 5 seconds)
$attempts = 0;
while (!isProcessRunning(3000) && $attempts < $max_attempts) {
    sleep(5); // Wait for 5 seconds
    $attempts++;
}

// If the React server is running, execute mkdir command for hi directory
if (isProcessRunning(3000)) {
    $resultHi = mkdir('hi');
    if (!$resultHi) {
        echo "Error: Failed to create the 'hi' directory.";
    }
    // Kill the React server process running on port 3000
    killProcess(3000);
    // Kill the Node.js runtime process
    exec("taskkill /F /IM node.exe");
} else {
    // If the React server didn't start within the specified time, display an error message
    echo "Error: React server did not start within the specified time.";
}
?>

спасибо @S.Imp за идею.

Другие вопросы по теме