What are some best practices for handling timeouts and process termination in PHP when using external tools?

When using external tools in PHP, it is important to handle timeouts and process termination gracefully to prevent hanging processes or resource leaks. One way to do this is by setting a timeout for the external tool execution and catching any exceptions or errors that may occur during the process.

// Set a timeout for the external tool execution
$timeout = 30; // 30 seconds

// Start the external tool process
$process = proc_open('external_tool_command', $descriptorspec, $pipes);

// Set the process timeout
if (function_exists('pcntl_signal')) {
    pcntl_signal(SIGALRM, function() use ($process) {
        proc_terminate($process, 9); // Terminate the process
    });
    pcntl_alarm($timeout);
}

// Check if the process is still running
$status = proc_get_status($process);
if ($status['running']) {
    // Process is still running, wait for it to finish
    proc_close($process);
} else {
    // Process has finished, handle the output
    $output = stream_get_contents($pipes[1]);
    fclose($pipes[1]);
}

// Reset the alarm
if (function_exists('pcntl_signal')) {
    pcntl_alarm(0);
}