Skip to content

Without Command Line

Bertie2011 edited this page Aug 29, 2021 · 2 revisions

In some applications, you might want to create a command-line-like interface, but you're not actually running on a command line. There are a few things to consider if you want to use CLIFramework outside the command line.

  • There is no $argv
    • The run methods on an application require a list of arguments.
      • Create or find a parser that converts a command string to an array, while taking quoted values (with spaces) into account.
      • Write code to automatically add the program name at the start of the array, so you don't have to specify it yourself. (Since $argv contains the name of the file at index 0 normally.)
  • There is no error output stream.
    • The error method in CLIFramework\Logger uses this output stream.
      • Create a subclass from Logger and override the base implementation of error($msg) to call $this->writeln($msg) instead of fprintf.
      • Instantiate the CLIFramework\ServiceContainer and set the logger entry to an instance of your custom logger using $container['logger'] = $logger
      • Pass the created ServiceContainer to the application constructor.
  • There is no input stream.
    • Do not use built-in input methods.
    • Autocorrect will assume you want to use the suggested command instead of asking. You might not want seemingly arbitrary commands from running if you made a typo.
      • Disable autocorrect by passing the --no-interact option.
  • Multiple people might have access in a production environment.
    • You probably don't want those people to modify system files through the built-in development commands.
      • Do not call parent::init() in the public init(): void method on the application to remove built-in commands.
      • Do register the help command manually using $this->addCommand('help', \CLIFramework\Command\HelpCommand::class).
  • Using the \r character to overwrite the current line might not be supported.
    • Do not use progress output or action logging.
  • The output stream is used for other purposes.
    • In a web environment, the output stream is normally used to render the web page. You do not want your console output to be inserted randomly.
      • Make sure to buffer the output, pull the string out of it and discard the buffer afterwards. That way nothing will be written to output directly.
        $app = new MyApp();
        try {
            ob_start();
            $app->runWithTry($argv);
        } catch (Exception $e) {
            $app->getLogger()->writeln(strval($e));
        } finally {
            $output = ob_get_clean();
        }
        // $output contains the output as string and can now be passed around freely and shown in the intended places.
  • Not all generated usage exceptions are caught.
    • Wrap the runWithTry($argv) call in a try/catch, see the code snippet above.