Console Commands
Learn how to create your own custom console commands.
Creating commands
For a command, you must define a callback, which can be a closure, callable, or a class method within the Commands namespace, using the method:
Console::action(
string $name,
string|callable $callback
): Inphinit\Experimental\Cli\Command
To test, add the following code to system/console.php:
use Inphinit\Experimental\Cli\Command;
$console->action('hello', function (Command $command, array $params, array $residues) {
echo 'Hello world!';
});
Then, in the project's root folder, run the command:
./run hello
In Windows, run:
run hello
If PHP is available via CLI, it is also possible to run:
php run hello
The callback doesn't need to return a value, or it can return null, but it's possible to send an exit status (also called an exit code or exit value ) when the command finishes, using int, for example:
use Inphinit\Experimental\Cli\Command;
$console->action('hello', function (Command $command, array $options, array $residues) {
if (condition) {
echo 'Success!';
return 0;
}
echo 'Fail!';
return 1;
});
Note that if you use return; or return null;, the exit status will be int(0).
Defining command options
A command can have one or more options, using:
Command::setOption(
string $long,
string|null $short = null,
int $modes = 0,
string|null $format = null,
string|null $description = null
)
Example:
use Inphinit\Experimental\Cli\Command;
$my_command = $console->action('flower', function (Command $command, array $options, array $residues) {
$name = $options['name'];
$color = $options['color'];
if ($name !== null) echo "Name: {$name}\n";
if ($color !== null) echo "Color: {$color}\n";
});
$my_command->setOption('name');
$my_command->setOption('color');
And you can run it:
./run flower --name Lily
Exit:
Name: Lily
Running:
./run flower --color red
You will get the output:
Color: red
Running:
./run flower --name Daisy --color purple
You will get the output:
Name: Daisy
Color: purple
The setOption() method always returns the command itself, which allows for simplifying the declaration in some cases, such as in the example:
use Inphinit\Experimental\Cli\Command;
$console->action('flower', function (Command $command, array $options, array $residues) {
// Something
})->setOption('name')->setOption('color');
Defining short options
Short options are aliases corresponding to long options that use a single character after the - sign; they must be defined in the second parameter of setOption(), for example:
$my_command->setOption('name', 'n');
$my_command->setOption('color', 'c');
Then you can run:
./run flower -n Daisy -c purple
Defining required options
Options are optional by default, and when the command does not receive a value, the item in the array coming in the second parameter of the callback (in the example $options) will receive the value null, but it is possible to make the option mandatory by passing the flag Command::ARG_REQUIRED:
$my_command->setOption('name', 'n', Command::ARG_REQUIRED); // Required
$my_command->setOption('color', 'c'); // Optional
When executing the command without the parameter, an exception will be thrown, and by convention, ./runthe exception message will be sent to the STDERR. Example:
./run flower --color red
Exit:
`--name` (or `-n`) is missing
If you need to set an option as mandatory without a short option, set the second parameter as null:
$my_command->setOption('name', null, Command::ARG_REQUIRED);
Defining non-value options
An option with no value should be flagged Command::ARG_NO_VALUE, for example:
use Inphinit\Experimental\Cli\Command;
$my_command = $console->action('hello', function (Command $command, array $options, array $residues) {
var_dump($options['message']);
var_dump($options['update']);
var_dump($options['restart']);
});
// Optional
$my_command->setOption('update', null, Command::ARG_NO_VALUE);
// Required
$my_command->setOption('restart', null, Command::ARG_NO_VALUE|Command::ARG_REQUIRED);
And it can be executed as:
./run hello --message "Hi!" --update --restart
When trying to pass a value:
./run hello --restart foobar
You will get the output:
`--restart` must not have a value, 'foobar' given
Validating the format of option values.
The fourth parameter setOption()can receive a complete regular expression , allowing considerable flexibility in validating the values, for example:
use Inphinit\Experimental\Cli\Command;
$my_command = $console->action('hello', function (Command $command, array $options, array $residues) {
var_dump($options['foo'], $options['bar']);
});
// Optional
$my_command->setOption('foo', null, 0, '#^[a-z]+$#');
// Required
$my_command->setOption('bar', null, Command::ARG_REQUIRED, '#^\d+$#');
Tolerating residual options
By default, commands that receive undefined options will cause the command to fail. Example:
./run hello --foo test --bar 1 --baz 1 --other -a -b -c
You will get the output:
Unexpected options: baz, other, a, b, c
But it's possible to ignore this error and continue the command using the method enableResidues(true)in the command:
use Inphinit\Experimental\Cli\Command;
$my_command = $console->action('hello', function (Command $command, array $options, array $residues) {
echo 'foo: ', $options['foo'], "\n";
echo 'bar: ', $options['bar'], "\n";
var_dump($residues);
});
$my_command->setOption('foo', null, 0, '#^[a-z]+$#');
$my_command->setOption('bar', null, Command::ARG_REQUIRED, '#^\d+$#');
$my_command->enableResidues(true);
The command will execute normally, and unexpected options will be passed to the third parameter of the callback (in the example $residues), obtaining the output:
foo: test
bar: 1
array(5) {
["baz"]=>
string(1) "1"
["other"]=>
NULL
["a"]=>
NULL
["b"]=>
NULL
["c"]=>
NULL
}
Using a class to define a command
To define one or more commands based on a class, create a file ./system/Commands/Example.phpcontaining:
<?php
namespace Commands;
use Inphinit\Experimental\Cli\Command;
class Example
{
/**
* @param \Inphinit\Experimental\Cli\Command $command
* @param array $options
* @param array $residues
*/
public function index(Command $command, array $options, array $residues)
{
echo 'Hello World!';
}
}
And then set it to ./system/console.php:
$console->action('hello', 'Example::index');
Executing a command outside the terminal
It's possible to execute the command via script, without going through a terminal. When creating a command in system/console.php, for example:
$console->action('mycommand', function (Command $command, array $params, array $residues) {
echo 'Hello!';
});
In a web route (in the file main.php), it's possible to call the command using:
use Inphinit\Experimental\Cli\Console;
$app->action('GET', '/run', function () {
$output = Console::run('mycommand', [], $status);
echo 'Exit status:', $status;
echo 'Output:', $output;
});
So when navigating to an address like http://localhost:5000/run, as in the example, you will see something like:
Exit status: 0
Output: Hello!
If the command expects options, use the second parameter as an associative array, without using ` --or` -, to send the values:
$output = Console::run('mycommand', [
'foo' => 'test 1',
'bar' => 'test 2'
], $status);
It will be the equivalent of:
./run mycommand --foo "teste 1" --bar "teste 2"
Built-in commands
Every project includes some useful commands to optimize or control the application:
| Command | Description |
|---|---|
run app:down |
Enable maintenance mode |
run app:up |
Disable maintenance mode |
run env:boot |
Optimizes the .env file environment variables by adding them to the boot cache |
run env:source |
Disable the cache of .env variables, making all requests require the application to parse the file |
run pkg:up |
Optimizes the loading of packages installed via Composer to use inphinit-autoload. Normally, it is not necessary to run this command, as it executes automatically when a package is installed or removed |
run serve |
Starts a development server |