Command Input/Output

  • class Cake\Console\ConsoleIo
  • CakePHP provides the ConsoleIo object to commands so that they caninteractively read user input and output information to the user.

Command Helpers

Command Helpers can be accessed and used from any command, shell or task:

  1. // Output some data as a table.
  2. $io->helper('Table')->output($data);
  3.  
  4. // Get a helper from a plugin.
  5. $io->helper('Plugin.HelperName')->output($data);

You can also get instances of helpers and call any public methods on them:

  1. // Get and use the Progress Helper.
  2. $progress = $io->helper('Progress');
  3. $progress->increment(10);
  4. $progress->draw();

Creating Helpers

While CakePHP comes with a few command helpers you can create more in yourapplication or plugins. As an example, we’ll create a simple helper to generatefancy headings. First create the src/Command/Helper/HeadingHelper.php and putthe following in it:

  1. <?php
  2. namespace App\Command\Helper;
  3.  
  4. use Cake\Console\Helper;
  5.  
  6. class HeadingHelper extends Helper
  7. {
  8. public function output($args)
  9. {
  10. $args += ['', '#', 3];
  11. $marker = str_repeat($args[1], $args[2]);
  12. $this->_io->out($marker . ' ' . $args[0] . ' ' . $marker);
  13. }
  14. }

We can then use this new helper in one of our shell commands by calling it:

  1. // With ### on either side
  2. $this->helper('Heading')->output(['It works!']);
  3.  
  4. // With ~~~~ on either side
  5. $this->helper('Heading')->output(['It works!', '~', 4]);

Helpers generally implement the output() method which takes an array ofparameters. However, because Console Helpers are vanilla classes they canimplement additional methods that take any form of arguments.

Note

Helpers can also live in src/Shell/Helper for backwards compatibility.

Built-In Helpers

Table Helper

The TableHelper assists in making well formatted ASCII art tables. Using it ispretty simple:

  1. $data = [
  2. ['Header 1', 'Header', 'Long Header'],
  3. ['short', 'Longish thing', 'short'],
  4. ['Longer thing', 'short', 'Longest Value'],
  5. ];
  6. $io->helper('Table')->output($data);
  7.  
  8. // Outputs
  9. +--------------+---------------+---------------+
  10. | Header 1 | Header | Long Header |
  11. +--------------+---------------+---------------+
  12. | short | Longish thing | short |
  13. | Longer thing | short | Longest Value |
  14. +--------------+---------------+---------------+

Progress Helper

The ProgressHelper can be used in two different ways. The simple mode lets youprovide a callback that is invoked until the progress is complete:

  1. $io->helper('Progress')->output(['callback' => function ($progress) {
  2. // Do work here.
  3. $progress->increment(20);
  4. $progress->draw();
  5. }]);

You can control the progress bar more by providing additional options:

  • total The total number of items in the progress bar. Defaultsto 100.
  • width The width of the progress bar. Defaults to 80.
  • callback The callback that will be called in a loop to advance theprogress bar.
    An example of all the options in use would be:
  1. $io->helper('Progress')->output([
  2. 'total' => 10,
  3. 'width' => 20,
  4. 'callback' => function ($progress) {
  5. $progress->increment(2);
  6. $progress->draw();
  7. }
  8. ]);

The progress helper can also be used manually to increment and re-render theprogress bar as necessary:

  1. $progress = $io->helper('Progress');
  2. $progress->init([
  3. 'total' => 10,
  4. 'width' => 20,
  5. ]);
  6.  
  7. $progress->increment(4);
  8. $progress->draw();

Getting User Input

  • Cake\Console\ConsoleIo::ask($question, $choices = null, $default = null)
  • When building interactive console applications you’ll need to get user input.CakePHP provides an easy way to do this:
  1. // Get arbitrary text from the user.
  2. $color = $io->ask('What color do you like?');
  3.  
  4. // Get a choice from the user.
  5. $selection = $io->askChoice('Red or Green?', ['R', 'G'], 'R');

Selection validation is case-insensitive.

Creating Files

  • Cake\Console\ConsoleIo::createFile($path, $contents)
  • Creating files is often important part of many console commands that helpautomate development and deployment. The createFile() method gives youa simple interface for creating files with interactive confirmation:
  1. // Create a file with confirmation on overwrite
  2. $io->createFile('bower.json', $stuff);
  3.  
  4. // Force overwriting without asking
  5. $io->createFile('bower.json', $stuff, true);

Creating Output

Writing to stdout and stderr is another routine operation CakePHP makeseasy:

  1. // Write to stdout
  2. $io->out('Normal message');
  3.  
  4. // Write to stderr
  5. $io->err('Error message');

In addition to vanilla output methods, CakePHP provides wrapper methods thatstyle output with appropriate ANSI colours:

  1. // Green text on stdout
  2. $io->success('Success message');
  3.  
  4. // Cyan text on stdout
  5. $io->info('Informational text');
  6.  
  7. // Blue text on stdout
  8. $io->comment('Additional context');
  9.  
  10. // Red text on stderr
  11. $io->error('Error text');
  12.  
  13. // Yellow text on stderr
  14. $io->warning('Warning text');

It also provides two convenience methods regarding the output level:

  1. // Would only appear when verbose output is enabled (-v)
  2. $io->verbose('Verbose message');
  3.  
  4. // Would appear at all levels.
  5. $io->quiet('Quiet message');

You can also create blank lines or draw lines of dashes:

  1. // Output 2 newlines
  2. $io->out($io->nl(2));
  3.  
  4. // Draw a horizontal line
  5. $io->hr();

Lastly, you can update the current line of text on the screen:

  1. $io->out('Counting down');
  2. $io->out('10', 0);
  3. for ($i = 9; $i > 0; $i--) {
  4. sleep(1);
  5. $io->overwrite($i, 0, 2);
  6. }

Note

It is important to remember, that you cannot overwrite textonce a new line has been output.

Output Levels

Console applications often need different levels of verbosity. For example, whenrunning as a cron job, most output is un-necessary. You can use output levels toflag output appropriately. The user of the shell, can then decide what level ofdetail they are interested in by setting the correct flag when calling thecommand. There are 3 levels:

  • QUIET - Only absolutely important information should be marked for quietoutput.
  • NORMAL - The default level, and normal usage.
  • VERBOSE - Mark messages that may be too noisy for everyday use, buthelpful for debugging as VERBOSE.
    You can mark output as follows:
  1. // Would appear at all levels.
  2. $io->out('Quiet message', 1, ConsoleIo::QUIET);
  3. $io->quiet('Quiet message');
  4.  
  5. // Would not appear when quiet output is toggled.
  6. $io->out('normal message', 1, ConsoleIo::NORMAL);
  7. $io->out('loud message', 1, ConsoleIo::VERBOSE);
  8. $io->verbose('Verbose output');
  9.  
  10. // Would only appear when verbose output is enabled.
  11. $io->out('extra message', 1, ConsoleIo::VERBOSE);
  12. $io->verbose('Verbose output');

You can control the output level of shells, by using the —quiet and—verbose options. These options are added by default, and allow you toconsistently control output levels inside your CakePHP comands.

The —quiet and —verbose options also control how logging data isoutput to stdout/stderr. Normally info and higher log messages are output tostdout/stderr. When —verbose is used, debug logs will be output to stdout.When —quiet is used, only warning and higher log messages will be output tostderr.

Styling Output

Styling output is done by including tags - just like HTML - in your output.These tags will be replaced with the correct ansi code sequence, orstripped if you are on a console that doesn’t support ansi codes. Thereare several built-in styles, and you can create more. The built-in ones are

  • success Success messages. Green text.
  • error Error messages. Red text.
  • warning Warning messages. Yellow text.
  • info Informational messages. Cyan text.
  • comment Additional text. Blue text.
  • question Text that is a question, added automatically by shell.
    You can create additional styles using $io->styles(). To declare anew output style you could do:
  1. $io->styles('flashy', ['text' => 'magenta', 'blink' => true]);

This would then allow you to use a <flashy> tag in your shell output, and ifansi colours are enabled, the following would be rendered as blinking magentatext $this->out('<flashy>Whoooa</flashy> Something went wrong');. Whendefining styles you can use the following colours for the text andbackground attributes:

  • black
  • blue
  • cyan
  • green
  • magenta
  • red
  • white
  • yellow
    You can also use the following options as boolean switches, setting them to atruthy value enables them.

  • blink

  • bold
  • reverse
  • underline
    Adding a style makes it available on all instances of ConsoleOutput as well,so you don’t have to redeclare styles for both stdout and stderr objects.

Turning Off Colouring

Although colouring is pretty, there may be times when you want to turn it off,or force it on:

  1. $io->outputAs(ConsoleOutput::RAW);

The above will put the output object into raw output mode. In raw output mode,no styling is done at all. There are three modes you can use.

  • ConsoleOutput::COLOR - Output with color escape codes in place.
  • ConsoleOutput::PLAIN - Plain text output, known style tags will bestripped from the output.
  • ConsoleOutput::RAW - Raw output, no styling or formatting will be done.This is a good mode to use if you are outputting XML or, want to debug whyyour styling isn’t working.
    By default on *nix systems ConsoleOutput objects default to colour output.On Windows systems, plain output is the default unless the ANSICONenvironment variable is present.