PHP code example of tobento / service-console

1. Go to this page and download the library: Download tobento/service-console library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

tobento / service-console example snippets


use Tobento\Service\Console\Symfony;
use Tobento\Service\Console\ConsoleInterface;
use Psr\Container\ContainerInterface;
use Psr\EventDispatcher\EventDispatcherInterface;

$console = new Symfony\Console(
    name: 'app',
    container: $container, // ContainerInterface
    
    // you may define a event dispatcher:
    eventDispatcher: $eventDispatcher, // EventDispatcherInterface
);

var_dump($console instanceof ConsoleInterface);
// bool(true)

$console->addCommand(SampleCommand::class);

// or
$console->addCommand(new SampleCommand());

$console->run();

use Tobento\Service\Console\ExecutedInterface;

$executed = $console->execute(
    command: SampleCommand::class,
    
    // passing arguments and options as array:
    input: [
        // passing arguments:
        'username' => 'Tom',

        // with array value:
        'username' => ['Tom', 'Tim'],

        // passing options:
        '--some-option' => 'value',

        // with array value:
        '--some-option' => ['value'],
    ],
    
    // or you may pass the command, arguments and options as string
    input: 'command:name Tom --bar=1'
);

var_dump($executed instanceof ExecutedInterface);
// bool(true)

$command = $executed->command(); // string
$code = $executed->code(); // int
$output = $executed->output(); // string

use Tobento\Service\Console\Command;
use Tobento\Service\Console\InteractorInterface;

$command = (new Command(name: 'name'))
    ->handle(function(InteractorInterface $io): int {
        // do sth:
        return 0;
    });
    
$console->execute(command: $command);

$console->addCommand(SampleCommand::class);

$console->execute(command: 'sample');

use Tobento\Service\Console\Command;
use Tobento\Service\Console\CommandInterface;
use Tobento\Service\Console\InteractorInterface;

$command = (new Command(name: 'mail:send'))
    // you may set a description:
    ->description('Send an email to a user(s)')
    
    // you may set a usage text:
    ->usage('Send emails ...')
    
    // you may add an argument(s):
    ->argument(
        name: 'user',
        description: 'The Id(s) of the user',
        variadic: true,
    )
    
    // you may add an option(s):
    ->option(
        name: 'queue',
        description: 'Whether the email should be queued',
    )
    
    // handle the command:
    ->handle(function(InteractorInterface $io, MailerInterface $mailer): int {
        // retrieve input arguments and options:
        $userIds = $io->argument('user');
        $queue = $io->option('queue');
        
        // send emails using the mailer...
        
        // you may write some output:
        $io->write(sprintf(
            'email(s) send to user ids %s queued [%s]',
            implode(',', $userIds),
            $queue ? 'true' : 'false',
        ));

        return Command::SUCCESS;
        // return Command::FAILURE;
        // return Command::INVALID;
    });
    
var_dump($command instanceof CommandInterface);
// bool(true)

use Tobento\Service\Console\Command;

$command = (new Command(name: 'sample'))
    ->argument(
        // The name of the argument:
        name: 'name',

        // you may define a description:
        description: 'Some description',

        // you may define a default value(s) (null default):
        value: ['foo', 'bar'], // mixed

        // set if the argument is optional (false default):
        optional: true,

        // if true expecting multiple values (false default):
        variadic: true,

        // not supported yet!
        suggestedValues: null,
    );

use Tobento\Service\Console\Command;

$command = (new Command(name: 'sample'))
    ->option(
        // The name of the option:
        name: 'name',

        // you may define a description:
        description: 'Some description',

        // you may define a default value(s) (null default):
        value: ['foo', 'bar'], // mixed
        
        // variadic:
        variadic: null, // (default)
        // acts as boolean value, if exists true, otherwise false.
        
        variadic: false,
        // optional value (e.g. --name or --name=foo) if not specified default value is used.
        
        variadic: true,
        // is variadic expecting multiple values (e.g. --name=foo --name=bar).
        // if not specified default values are used.
     
        // not supported yet!
        suggestedValues: null,
    );

use Tobento\Service\Console\AbstractCommand;
use Tobento\Service\Console\InteractorInterface;

class SendEmails extends AbstractCommand
{
    /**
     * The command name.
     */
    public const NAME = 'email:send';
    
    /**
     * The command description.
     */
    public const DESC = 'Send an email to a user(s)';
    
    /**
     * The command usage text.
     */
    public const USAGE = 'Send emails ...';
    
    /**
     * Create a new instance.
     */
    public function __construct()
    {
        // you may add an argument(s):
        $this->argument(
            name: 'user',
            description: 'The Id(s) of the user',
            variadic: true,
        );
        
        // you may add an option(s):
        $this->option(
            name: 'queue',
            description: 'Whether the email should be queued',
        );
    }
    
    /**
     * Handle the command.
     *
     * @param InteractorInterface $io
     * @return int The exit status code: 
     *     0 SUCCESS
     *     1 FAILURE If some error happened during the execution
     *     2 INVALID To indicate incorrect command usage e.g. invalid options
     */
    public function handle(InteractorInterface $io, MailerInterface $mailer): int
    {
        // retrieve input arguments and options:
        $userIds = $io->argument('user');
        $queue = $io->option('queue');
        
        // send emails using the mailer...
        
        // you may write some output:
        $io->write(sprintf(
            'email(s) send to user ids %s queued [%s]',
            implode(',', $userIds),
            $queue ? 'true' : 'false',
        ));
        
        return 0;
        // or use the available constants:
        // return static::SUCCESS;
        // return static::FAILURE;
        // return static::INVALID;
    }
}

use Tobento\Service\Console\AbstractCommand;
use Tobento\Service\Console\InteractorInterface;

class SendEmails extends AbstractCommand
{
    /**
     * The signature of the console command.
     */
    public const SIGNATURE = '
        mail:send | Send an email to a user(s)
        {user : The Id(s) of the user}
        {--queue : Whether the email should be queued}
    ';
    
    /**
     * Handle the command.
     *
     * @param InteractorInterface $io
     * @return int The exit status code: 
     *     0 SUCCESS
     *     1 FAILURE If some error happened during the execution
     *     2 INVALID To indicate incorrect command usage e.g. invalid options
     */
    public function handle(InteractorInterface $io): int
    {
        return 0;
    }
}

use Tobento\Service\Console\Command;
use Tobento\Service\Console\InteractorInterface;

$command = (new Command(name: 'mail:send'))
    // handle the command:
    ->handle(function(InteractorInterface $io): int {
        // ...
        // use the interactor $io to interact
        // ...
    });

// Argument(s):
$value = $io->argument(name: 'name');

// all values indexed by the argument name:
$values = $io->arguments();

// Option(s):
$value = $io->option(name: 'name');

// all values indexed by the option name:
$values = $io->options();

// Argument with variadic: false
$value = $io->argument(name: 'name');
// NULL, if the argument was not passed when running the command
// Not NULL, if the argument was passed when running the command

// Argument with variadic: true
$value = $io->argument(name: 'name');
// Array empty if the argument was not passed when running the command

// Option with variadic: null
$value = $io->option(name: 'name');
// bool(false), if the option was not passed when running the command
// bool(true), if the option was passed when running the command

// Option with variadic: false
$value = $io->option(name: 'name');
// NULL, if the option was not passed when running the command
// Not NULL, if the option was passed when running the command

// Option with variadic: true
$value = $io->option(name: 'name');
// Array, empty if the option was not passed when running the command

// if this command was run as:
// php ap command:name foo --bar --baz=1

$rawInput = $io->rawInput();
// ['command:name', 'foo', '--bar', '--baz=1']

// you may exclude the command name:
$rawInput = $io->rawInput(withoutCommandName: false);
// ['foo', '--bar', '--baz=1']

$io->write('Some text');

$io->write('Some Text', 'newline');
$io->write('Some Text', newline: 1);

// Write a single blank line:
$io->newLine();

// Write three blank lines:
$io->newLine(num: 3);

// Write specific messages:
$io->info('An info message');
$io->comment('A comment message');
$io->warning('A warning message');
$io->error('An error message');
$io->success('A success message');

$io->write('<comment>Some text</comment>');

$io->write('<fg=red>Some text</>');
$io->write('<bg=red>Some text</>');
$io->write('<fg=white;bg=red>Some text</>');

$io->table(
    headers: ['Name', 'Email'],
    rows: [
        ['Tom', '[email protected]'],
    ],
);

$name = $io->ask('What is your name?');

// With validator:
$name = $io->ask('What is your name?', validator: function(string $answer): void {
    if ($answer !== 'something') {
        throw new \Exception('Your answer is incorrect');
    }
});

// With max attempts:
$name = $io->ask('What is your name?', attempts: 2);

$password = $io->secret('What is the password?');

// With validator:
$name = $io->secret('What is your name?', validator: function(string $answer): void {
    if ($answer !== 'something') {
        throw new \Exception('Your answer is incorrect');
    }
});

// With max attempts:
$name = $io->secret('What is your name?', attempts: 2);

if ($io->confirm('Do you wish to continue?', default: true)) {
    // ...
}

$color = $io->choice(
    question: 'What color do you wish to use?',
    choices: ['red', 'blue'],
    default: 'red',
    multiselect: true,
);

$io->progressStart(max: 5);

foreach (range(0, 5) as $number) {
    sleep(1);
    $io->progressAdvance(step: 1);
}

$io->progressFinish();

if ($io->isVerbose('vv')) {
    $io->write('Some Text');
}

// or:
$io->write('Some Text', 'v');
$io->write('Some Text', 'vv');
$io->write('Some Text', 'vvv');

use Tobento\Service\Console\Command;
use Tobento\Service\Console\InteractorInterface;
use Tobento\Service\Console\Parameter;

$command = (new Command(name: 'mail:send'))
    ->parameter(new Parameter\IgnoreValidationErrors());
    
    // handle the command:
    ->handle(function(InteractorInterface $io): int {
        return Command::SUCCESS;
    });

use PHPUnit\Framework\TestCase;
use Tobento\Service\Console\Test\TestCommand;

class SampleCommandTest extends TestCase
{
    public function testCommand()
    {
        (new TestCommand(command: SampleCommand::class))
            // output expectations:
            ->expectsOutput('lorem')
            ->doesntExpectOutput('ipsum')
            ->expectsOutputToContain('lorem')
            ->doesntExpectOutputToContain('ipsum')
            ->expectsTable(
                headers: ['Name', 'Email'],
                rows: [
                    ['Tim', '[email protected]'],
                ],
            )
            
            // questions expectations:
            ->expectsQuestion('What is your name?', answer: 'Tom')
            ->expectsQuestion('What colors do you wish to use?', answer: ['red', 'yellow'])
            ->expectsQuestion('Do you wish to continue?', answer: true)
            
            // exit code expectation:
            ->expectsExitCode(0)
            
            // execute test:
            ->execute();
    }
}

use PHPUnit\Framework\TestCase;
use Tobento\Service\Console\Test\TestCommand;
use Tobento\Service\Console\CommandInterface;

class SampleCommandTest extends TestCase
{
    public function testCommand()
    {
        (new TestCommand(
            command: SampleCommand::class, // string|CommandInterface
            input: [
                // passing arguments:
                'username' => 'Tom',
                
                // with array value:
                'username' => ['Tom', 'Tim'],

                // passing options:
                '--some-option' => 'value',
                
                // with array value:
                '--some-option' => ['value'],
                
                // pass null for options with variadic: null
                '--some-option' => null,
                
            ],
        ))
        // set expectations:
        ->expectsOutput('lorem')
        ->expectsExitCode(0)

        // execute test:
        ->execute();
    }
}

use PHPUnit\Framework\TestCase;
use Tobento\Service\Console\Test\TestCommand;
use Tobento\Service\Console\ConsoleInterface;
use Psr\Container\ContainerInterface;

class SampleCommandTest extends TestCase
{
    public function testCommand()
    {
        (new TestCommand(command: SampleCommand::class))
            ->expectsExitCode(0)
            
            // if no dependencies
            ->execute() // null
            
            // passing the console to test on:
            ->execute($console) // ConsoleInterface
            
            // or just passing the container
            // (recommended way as console independent):
            ->execute($container); // ContainerInterface
    }
}

use PHPUnit\Framework\TestCase;
use Tobento\Service\Console\Test\TestCommand;

class SampleCommandTest extends TestCase
{
    private function command(): TestCommand
    {
        return new TestCommand(command: SampleCommand::class);
    }
    
    public function testCommand()
    {
        $this->command()
            ->withInput([
                'username' => 'Tom',            
            ])
            ->expectsExitCode(0)
            ->execute();
    }
}

use Tobento\Service\Console\Symfony;
use Tobento\Service\Console\ConsoleInterface;
use Psr\Container\ContainerInterface;
use Psr\EventDispatcher\EventDispatcherInterface;

$console = new Symfony\Console(
    name: 'app',
    container: $container, // ContainerInterface
    
    // you may define a event dispatcher:
    eventDispatcher: $eventDispatcher, // EventDispatcherInterface
);

var_dump($console instanceof ConsoleInterface);
// bool(true)

use Tobento\Service\Console\Symfony;
use Tobento\Service\Console\ConsoleInterface;
use Tobento\Service\Console\InteractorInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Psr\Container\ContainerInterface;

$interactorFactory = function(
    Command $command,
    InputInterface $input,
    OutputInterface $output
): InteractorInterface {
    return new Symfony\Interactor(
        command: $command,
        input: $input,
        output: $output,
        style: null, // null|SymfonyStyle
    );
    
    // or create another Interactor fitting your needs
};

$console = new Symfony\Console(
    name: 'app',
    container: $container, // ContainerInterface
    interactorFactory: $interactorFactory,
);

var_dump($console instanceof ConsoleInterface);
// bool(true)