Luminova Framework

PHP Luminova: Process Execution Handler

Last updated: 2024-10-17 14:10:13

Process Handler simplifies executing command processes. It supports multiple execution methods like popen, proc_open, and shell_exec, as well as running closures and working with stream interfaces.

The Process Handler class provides a flexible interface for executing commands or custom code in PHP, with built-in support for various execution methods. It allows commands to be run through executors like popen, proc_open, shell_exec, and exec, as well as directly executing PHP closures and handle responses such generators, or stream resources, array, string and many more.

In addition, the process class leverages PHP 8.1 Fiber (if available) to enable asynchronous execution, allowing non-blocking interaction with commands or user-defined code. This enables the class to wait for processes to complete while offering optional timeouts for checking the status of the process. Once the process completes, the response can be retrieved efficiently.


Features:

  • Multiple Executors: The class supports running processes using different command execution mechanisms such as:
    • popen
    • proc_open
    • shell_exec
    • exec
  • Closure Support: It can execute callable PHP functions or generators, allowing developers to easily run custom code or produce dynamic outputs.
  • Stream Interface: It handles stream resources for reading or writing data through file descriptors, making it suitable for dealing with files, network streams, etc.
  • Process Lifecycle Management: The class can manage the lifecycle of a process, including starting, running, waiting for completion, and retrieving responses or outputs.
  • Timeouts: It includes the ability to wait for a process with a defined timeout to avoid long-running or hanging processes.

Example Usages:

  1. Executing with proc_open:For advanced command execution scenarios, it supports running commands using proc_open, allowing more fine-grained control over input/output streams.

    $process = Process::withCommand('sleep 10 && echo "Sleep is completed"', Process::EXECUTOR_PROC_OPEN);
    $process->run();
    $process->wait(15); // Wait for up to 15 seconds
    
    if ($process->isComplete()) {
      // Get and output the response
      $response = $process->getResponse();
      echo "Command output:\n";
      var_export($response);
    }
  2. Executing a Callable Function:It also supports running a PHP closure or callable, making it versatile for various tasks beyond shell commands.

    $process = Process::withCallback(function() {
       return "Hello, World!";
    });
    $process->run();
  3. Shell Command Execution with shell_exec:This feature enables executing system commands using shell_exec and capturing their output.

    $process = Process::withCommand('ls -la', Process::EXECUTOR_SHELL);
    $process->run();
  4. Handling Stream Resources:The class can read from or write to streams, like files or network resources, using the stream interface.

    $stream = fopen('path/to/file.txt', 'r');
    $process = Process::withStream($stream);
    $process->run();
    $process->wait();
    
    fclose($stream);
    
    // Get the contents read from the stream
    if ($process->isComplete()) {
      $response = $process->getResponse();
      echo "Stream content:\n$response";
    }
  5. Running a Command with popen:The Process class allows for running shell commands using popen, providing control over the command output and process flow.

    $process = Process::withCommand('ls -la', Process::EXECUTOR_POPEN);
  6. Waiting for Generator Completion:It can run and wait for PHP generators to complete, making it a versatile tool for handling asynchronous-like operations.

    $generator = function() {
      yield "Part 1";
      yield "Part 2";
    };
    $process = Process::withCallback($generator);
    $process->run();
    $process->wait();
    
    // Get the generator's output
    if ($process->isComplete()) {
      $response = $process->getResponse();
      echo "Generator output:\n" . implode("\n", (array) $response);
    }

  • Class namespace: \Luminova\Utils\Process

Constants

These constants are predefined process executors which can be pass directory during initialization or along with withCommand method.

ConstantVisibilityTypeDescription
EXECUTOR_POPENpublicstringExecutes a command using popen, opening a pipe for process I/O.
EXECUTOR_EXECpublicstringExecutes a command using exec, running it directly via the shell.
EXECUTOR_SHELLpublicstringExecutes a command using shell_exec, capturing output from the shell.
EXECUTOR_PROC_OPENpublicstringExecutes a command using proc_open, offering more control over process execution and I/O streams.
EXECUTOR_CALLBACKpublicstringExecutes process using a custom callback function, allowing flexible execution logic.
EXECUTOR_STREAMpublicstringExecutes a process using streams, enabling direct access to input/output streams during execution.

Methods

constructor

Process constructor.

public __construct(
    \Psr\Http\Message\StreamInterface|\Luminova\Storages\Stream|\Closure|resource|callable|array|string $input, 
    string $executor, 
    ?string $cwd = null, 
    ?array<string,mixed> $env = null
): mixed

Parameters:

ParameterTypeDescription
$input\Psr\Http\Message\StreamInterface|\Luminova\Storages\Stream|\Closure|resource|callable|array|stringCommand string, callable, or stream to be executed.
$executorstringThe process executor type (e.g, Process::EXECUTOR_*).
Can be one of the defined executor constants.
$cwdstring|nullOptional working directory (default: null).
$envarray<string,mixed>|nullOptional environment variables.

__sleep

Process serialization is not supported.

public __sleep(): array

Throws:


__wakeup

Process deserialization is not supported.

public __wakeup(): void

Throws:


run

Runs the process based on the provided input and executor.

public run(): mixed

Throws:


withCallback

Creates a Process instance with a callback.

public static withCallback(callable $callable): self

Parameters:

ParameterTypeDescription
$callablecallableThe callable to be executed.

Return Value:

Process - Return new static process instance.


withStream

Creates a Process instance with a stream.

public static withStream(\Psr\Http\Message\StreamInterface|\Luminova\Storages\Stream|resource $stream): self

Parameters:

ParameterTypeDescription
$stream\Psr\Http\Message\StreamInterface|\Luminova\Storages\Stream|resourceThe stream resource to read from.

Return Value:

Process - Return new static process instance.


withCommand

Creates a Process instance with a command.

public static withCommand(
    array|string $command, 
    string $executor = self::EXECUTOR_POPEN, 
    string|null $cwd = null,
    array<string,mixed>|null $envs = null
): self

Parameters:

ParameterTypeDescription
$commandarray|stringThe command to be executed.
$executorstringThe executor method to use (default: Process::EXECUTOR_POPEN).
$cwdstring|nullOptional working directory (default: null).
$envsarray<string,mixed>|nullOptional environment variables (default: null).

Return Value:

Process - Return new static process instance.


isComplete

Checks if the process has completed execution.

public isComplete(): bool

Return Value:

bool - Return true if the process has finished; otherwise, false.


isRunning

Checks if the process has completed execution.

public isRunning(): bool

Return Value:

bool - Return true if the process has finished; otherwise, false.


isPtySupported

Determines if PTY (Pseudo-Terminal) is supported on the current system.

public static isPtySupported(): bool

Return Value:

bool - Return true if PTY is supported, false otherwise.


isTtySupported

Checks if the current system supports TTY (Teletypewriter).

public static isTtySupported(): bool

Return Value:

bool - Return true if TTY is supported, false otherwise.


getResponse

Retrieves the output response from the executed process.The response output, which can be of any type (e.g., string, array).

public getResponse(): mixed

Return Value:

mixed - Returns null if the process has not yet run or if no response is available.


getPid

Returns the Pid (process identifier), if applicable.

public getPid(): ?int

Return Value:

int|null - The process id if running, null otherwise


getInfo

Returns the Pid (process identifier), if applicable.

public getInfo(): array|false

Return Value:

array|false - The process id if running, null otherwise


getStartTime

Retrieve the process start time in seconds.

public getStartTime(): float

Return Value:

float - Return the process start time.

Throws:


getWorkingDirectory

Gets the working directory.

public getWorkingDirectory(): ?string

Return Value:

string|null - Return the current working directory.


getCommand

Sanitize, replace and retrieve command.

public getCommand(): string

Return Value:

string - Return command string to be executed.

Throws:


setWorkingDirectory

Sets the current working directory.

public setWorkingDirectory(string $cwd): self

Parameters:

ParameterTypeDescription
$cwdstringThe current working directory.

Return Value:

self - Return the instance of process class.

Throws:


setEnvironment

Sets the environment variables.

public setEnvironment(array<string,mixed> $envs): self

Parameters:

ParameterTypeDescription
$envsarray<string,mixed>The environment variables.

Return Value:

self - Return the instance of process class.

Throws:


setMode

Sets the mode for opens process file pointer.

public setMode(string $mode): self

Parameters:

ParameterTypeDescription
$modestringThe mode to use.

Return Value:

self - Return the instance of process class.

Throws:


setDescriptors

Sets the descriptors specifications.

public setDescriptors(array<int,array> $descriptors): self

Parameters:

ParameterTypeDescription
$descriptorsarray<int,array>The descriptors specifications.

Return Value:

self - Return the instance of process class.

Throws:


setOptions

Set the process options before execution.

This method allows setting specific options for the process, such as blocking pipes orcreating a new process group. Options cannot be modified once the process is running.

public setOptions(array<string,mixed> $options): 

Parameters:

ParameterTypeDescription
$optionsarray<string,mixed>An associative array of options to set.

Return Value:

self - Return the instance of process class.

Throws:

Supported options include:

  • blocking_pipes: Controls whether the pipes should block during I/O.
  • create_process_group: Determines if the process should be run in a new group.
  • create_new_console: Launches the process in a new console window (Windows only).
  • bypass_shell: Bypass the shell when launching the process (Linux/Windows).
  • detach_process: Detaches the process, allowing it to run independently (Linux/Windows).
  • use_pty: Use a pseudo-terminal (PTY) for the process (Unix systems only).
  • inherit_environment: Inherit the environment variables from the parent process.
  • redirect_stderr: Redirect stderr to stdout (combine output streams).
  • suppress_errors: Suppress PHP errors or warnings during the process execution.

getDescriptors

Gets the descriptors for the process.

public getDescriptors(): array

Return Value:

array - Return the descriptors for the process based on the operating system.


wait

Waits for the process to complete and collects output.

public wait(int $timeout): void

Parameters:

ParameterTypeDescription
$timeoutintMaximum time to wait in seconds (default: 0 for no timeout).

Throws: