This version is outdated. You should upgrade your project to Mako 12.1!
Command line

Commands



The Mako command line tool comes with a set of useful commands but you can also create your own.


Basics

Getting started

All commands must extend the phpmako\reactor\Command base command and implement the phpexecute method.

<?php

namespace app\console\commands;

use mako\reactor\Command;

class Hello extends Command
{
	public function execute()
	{
		$this->write('Hello, World!');
	}
}

You can return a custom exit code from your command's execute method. The default code if none is returned is 0.

Arguments and options

Passing arguments to a command is easy.

<?php

namespace app\console\commands;

use mako\reactor\Command;

class Hello extends Command
{
	public function execute($arg2)
	{
		$this->write('Hello, ' . $arg2 . '!');
	}
}

php$arg0 is the reactor script and php$arg1 is the name of the command.

You can now execute your command from the command line.

php reactor hello dude

You can, of course, also use options or named arguments.

<?php

namespace app\console\commands;

use mako\reactor\Command;

class Hello extends Command
{
	public function execute($name)
	{
		$this->write('Hello, ' . $name . '!');
	}
}

You can now execute your command from the command line.

php reactor hello --name=dude

Options can also be used as boolean flags.

<?php

namespace app\console\commands;

use mako\reactor\Command;

class Hello extends Command
{
	public function execute($shout = false)
	{
		$greeting = 'Hello, World!';

		if($shout !== false)
		{
			$greeting = strtoupper($greeting);
		}

		$this->write($greeting);
	}
}

You can now execute your command from the command line.

php reactor hello --shout

Both arguments and options can be documented using the php$commandInformation property.

protected $commandInformation =
[
	'description' => 'Print out a greeting.',
	'options' =>
	[
		'shout' =>
		[
			'optional'    => true,
			'description' => 'Should we output upper-case?',
		],
	],
];

It is generally a good idea to document your arguments and options since this allows for a more user friendly error message if a required argument or option is omitted. You can also set the php$isStrict property to phpTRUE if you want the command to fail if a non-documented argument or option is used.

Registering commands

You'll have to register your command with the reactor command line tool before you can use it.

Commands are registered in the phpapp/config/application.php configuration file. The array key is the name of your command and the value is the command class name.

Check out the this page of the documentation to see how you register your custom commands in packages.

'commands' =>
[
	'hello' => 'app\console\commands\Hello',
],

You can now call your custom command like this.

php reactor hello

Input

Helpers

The phpquestion method lets you ask the user for input.

$input = $this->question('How old are you?');

You can also specify a default return value in the event that the user chooses not to enter anything. The default return value for empty input is phpNULL.

$input = $this->question('How old are you?', 25);

The phpsecret method lets you ask the user for hidden input.

$input = $this->secret('Password:');

You can also specify a default return value in the event that the user chooses not to enter anything. The default return value for empty input is phpNULL.

$input = $this->secret('Password:', false);

The phpsecret method will throw a phpRuntimeException if its unable to hide the user input. You can make the method fall back to non-hidden input by passing phpTRUE to the optional third parameter.

The phpconfirm method lets you ask the user to confirm their action.

if($this->confirm('Do you want to delete all your files?'))
{
	// Delete all files
}

The default answer is phpn (false) but you can choose to make phpy (true) the default answer.

if($this->confirm('Do you want to delete all your files?', 'y'))
{
	// Delete all files
}

Output

Helpers

The phpwrite method lets you write output.

$this->write('Hello, World!');

The method writes to phpSTDOUT by default but you can make it write to phpSTDERR like this.

$this->write('Hello, World!', Output::ERROR);

There's also a handy phperror method that lets you write to phpSTDERR.

$this->error('Hello, World!');

The phpnl method writes a newline to the output.

$this->nl();

The phpclear method lets you clear all output from the terminal window.

$this->clear();

The phpbell method rings the terminal bell.

$this->bell();

You can also make it ring multiple times if you want to.

$this->bell(3);

The phpcountdown method will print a countdown that disappears after n seconds.

$this->countdown(5);

The phpprogressBar method will let you display a nice progressbar. This is useful if your command is processing multiple items.

$items = 100;

$progressbar = $this->progressBar($items);

for($i = 0; $i < $items; $i++)
{
	$progressbar->advance();
}

The phptable method lets you output a nice ASCII table.

$this->table(['Col1', 'Col2'], [['R1 C1', 'R1 C2'], ['R2 C1', 'R2 C2']]);

This code above will result in a table looking like this.

-----------------
| Col1  | Col2  |
-----------------
| R1 C1 | R1 C2 |
| R2 C1 | R2 C2 |
-----------------

The phpol method lets you output an ordered list.

$this->ol(['one', 'two', 'three', ['one', 'two'], 'four']);

The example above will output the following list.

1. one
2. two
3. three
   1. one
   2. two
4. four

The phpul method lets you output an unordered list.

$this->ul(['one', 'two', 'three', ['one', 'two'], 'four']);

The example above will output the following list.

* one
* two
* three
  * one
  * two
* four

Formatting

You can format your output using formatting tags.

$this->write('<blue>Hello, World!</blue>');

You can also nest formatting tags. Just make sure to close them in the right order.

$this->write('<bg_green><black>Hello, World</black><yellow>!<yellow></bg_green>');

If you find yourself using the same nested set of formatting tags over and over again, then you'll probably want to define your own custom tags. This can be done using the phpFormatter::addStyle() method.

$this->output->getFormatter()->addStyle('awesome', ['bg_green', 'black', 'blinking']);

Tags can also be escaped by prepending them with a backslash.

$this->write('\<blue>Hello, World\</blue>');

If you want to escape all tags in a string then you can use the phpFormatter::escape() method.

$escaped = $this->output->getFormatter()->escape($string);
Tag Description
clear Clears all formatting styles
bold Bold text
faded Faded colors
underlined Underlined text
blinking Blinking text
reversed Reversed text
hidden Hidden text
black Black text
red Red text
green Green text
yellow Yellow text
blue Blue text
purple Purple text
cyan Cyan text
white white text
bg_black Black background
bg_red Red background
bg_green Green background
bg_yellow Yellow background
bg_blue Blue background
bg_purple Purple background
bg_cyan Cyan background
bg_white white background

Note that formatting will only work on linux/unix and windows consoles with ANSI support.

Formatting is stripped when the output is redirected (e.g. to a log file phpphp reactor command > log.txt).


Calling commands from commands

If you need to call a command from another command then you can use the FireTrait.

The fire method executes your command in a separate process and lets you handle the output using a closure.

<?php

namespace app\console\commands;

use mako\reactor\Command;
use mako\reactor\traits\FireTrait;

class Proxy extends Command
{
	use FireTrait;

	public function execute()
	{
		$this->fire('hello --name=dude', function($buffer)
		{
			$this->output->write($buffer);
		});
	}
}

If you don't want to wait for the command to finish then you can start a background process using the fireAndForget method.

<?php

namespace app\console\commands;

use mako\reactor\Command;
use mako\reactor\traits\FireTrait;

class Manager extends Command
{
	use FireTrait;

	public function execute()
	{
		$this->fireAndForget('worker --file=1 >> /var/log/worker');
	}
}

Dependency injection

Commands are instantiated by the dependency injection container. This makes it easy to inject your dependencies using the constructor.

<?php

namespace app\console\commands;

use mako\reactor\Command;

class Hello extends Command
{
	protected $config;

	public function __construct(Input $input, Output $output, Config $config)
	{
		parent::__construct($input, $output);

		$this->config = $config;
	}
}

Note that commands expect the first two constructor parameters to be instances of the phpInput and phpOutput classes.

You can also inject your dependencies directly into the phpexecute method since its executed by the phpContainer::call() method.

public function execute(Config $config)
{
	$foo = $config->get('settings.foo');
}

Commands are also phpcontainer aware. You can read more about what this means here.