<?php
namespace XF\Util;
class Exec
{
/**
* Helper to run command via exec with properly escaped arguments.
* This function will wait for the command to finish.
*
* Note: This function should only be called if you can guarantee that exec is available.
*
* @param $command
* @param int|null $resultCode
* @param ...$args
*
* @return array
*/
public static function executeCommand($command, int &$resultCode = null, ...$args): array
{
return self::_executeCommand($command, false, $resultCode, $args);
}
/**
* Helper to run command via exec with properly escaped arguments asynchronously.
* This function will execute the command silently with no output.
* There is no indication of success with this method.
*
* Note: This function should only be called if you can guarantee that exec is available.
*
* @param $command
* @param ...$args
*/
public static function executeAsyncCommand($command, ...$args)
{
self::_executeCommand($command, true, $null, $args);
}
protected static function _executeCommand($command, bool $async, int &$resultCode = null, array $args = []): array
{
self::assertCanExecuteCommand($async);
if ($args)
{
$args = array_map('escapeshellarg', $args);
$command = vsprintf($command, $args);
}
$output = [];
if ($async)
{
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') // Windows
{
if (class_exists('COM', false))
{
$shell = new \COM("WScript.Shell");
$shell->Run($command, 0, false);
}
else
{
pclose(popen("start \"XF\" /B $command", 'r'));
}
}
else
{
exec("nohup $command > /dev/null 2> /dev/null &");
}
}
else
{
exec($command, $output, $resultCode);
}
return $output;
}
protected static function assertCanExecuteCommand(bool $async)
{
if ($async)
{
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') // Windows
{
if (!class_exists('COM', false))
{
if (!function_exists('popen') || !function_exists('pclose'))
{
throw new \BadFunctionCallException("Cannot run specified command as class COM or functions pclose/popen are unavailable on this system.");
}
}
}
else
{
if (!function_exists('exec'))
{
throw new \BadFunctionCallException("Cannot run specified command as exec is unavailable on this system.");
}
}
}
else
{
if (!function_exists('exec'))
{
throw new \BadFunctionCallException("Cannot run specified command as exec is unavailable on this system.");
}
}
}
}