phalcon/cli-options-parser
A simple, lightweight PHP library for parsing command-line options and arguments in Phalcon CLI applications. Define expected flags, parameters, and switches, then read and validate user input with sensible defaults, type checks, and clear error messages for robust console tooling.
Installation
composer require phalcon/cli-options-parser:^2.0
v2.0.0 requires PHP 8.0+. If you are still on PHP 7.4, pin the previous major line instead:
composer require phalcon/cli-options-parser:^1.0
No manual autoload block is normally needed — Composer resolves the package's own PSR-4 mapping. Only add one if you are vendoring the source:
"autoload": {
"psr-4": {
"Phalcon\\Cli\\": "vendor/phalcon/cli-options-parser/src/"
}
}
Run composer dump-autoload after any autoload change.
First Use Case Parse CLI arguments in a Phalcon CLI application:
use Phalcon\Cli\OptionsParser;
$parser = new OptionsParser();
$parser->setDescription('My CLI tool');
// Define options
$parser->addOption('help', 'h', 'Show this help message');
$parser->addOption('verbose', 'v', 'Enable verbose output');
// Parse arguments
$options = $parser->parse();
Where to Look First
.github/workflows/ — with #17 merged, this is now the authoritative statement of which PHP versions and dependency sets are tested.Phalcon\Cli\OptionsParser class docs (if generated)./tests (if provided).Option Definition
$parser = new OptionsParser();
$parser->addOption(
'name', // Long option (e.g., `--name`)
'n', // Short option (e.g., `-n`)
'Description of the option',
true, // Required?
'default' // Default value
);
Argument Handling Parse positional arguments (non-option inputs):
$parser->addArgument('file', 'Input file path', true);
$options = $parser->parse();
$filePath = $options->getArgument('file');
Validation Validate parsed options:
if (!$parser->isValid()) {
echo $parser->getErrorMessage();
exit(1);
}
Help Generation Auto-generate help text:
$parser->setDescription('Processes files with options.');
$parser->addOption('help', 'h', 'Show help');
if ($options->getOption('help')) {
echo $parser->getHelpMessage();
exit(0);
}
Integration with Phalcon CLI
Use in a Phalcon\Cli\Console controller:
class MyCliController extends \Phalcon\Cli\Console
{
public function mainAction()
{
$parser = new OptionsParser();
$parser->addOption('input', 'i', 'Input file', true);
$options = $parser->parse();
// Use $options->getOption('input')
}
}
Custom Option Types (PHP 8 flavour) With v2.0.0's PHP 8.0 floor you can type the value side of your options properly instead of trusting strings:
enum OutputFormat: string
{
case Json = 'json';
case Table = 'table';
}
$format = OutputFormat::tryFrom($options->getOption('format') ?? '')
?? throw new \RuntimeException('Unknown --format value');
Extend Phalcon\Cli\OptionsParser and put the conversion/validation in a readonly subclass or a small resolver service rather than bolting it onto the parser itself.
Subcommands
Dispatch with match now that PHP 8 is guaranteed:
$parser->addOption('command', 'c', 'Command to run', true);
$command = $options->getOption('command');
match ($command) {
'migrate' => $this->runMigrations($options),
'seed' => $this->runSeed($options),
default => throw new \InvalidArgumentException("Unknown command: {$command}"),
};
Environment Awareness
Combine with Phalcon\Config for environment-specific defaults:
$config = new \Phalcon\Config\Adapter\Ini('config.ini');
$parser->addOption('timeout', 't', 'Timeout (sec)', false, $config->timeout);
The v2.0.0 Upgrade Is a Major Bump The headline change is PHP 8.0+. That is a hard breaking change for:
Before upgrading: composer why-not phalcon/cli-options-parser 2.0 to see what is holding you back, then composer update phalcon/cli-options-parser --with-dependencies.
"Tidied Up the Code" Is an Unspecified Change
The release notes call this out without detail. Code tidying frequently means visibility changes (protected → private) and renamed internals. If you extended OptionsParser or the parsed-options object, review the diff between the two tags before deploying — subclassed methods are the most likely casualty.
Option Precedence
Short options (-n) override long options (--name) if both are provided. Test edge cases:
php script.php --name=value -n another_value
Argument vs. Option Confusion Positional arguments are not options. Ensure users know the difference:
# Correct: `php script.php -i input.txt` (option)
# Incorrect: `php script.php input.txt -i` (argument first)
Validation Overhead
isValid() checks all options/arguments. For partial validation, manually check:
if (!$options->getOption('required_flag')) {
throw new \RuntimeException('Flag is required');
}
Help Message Formatting
Long descriptions may wrap poorly. Use --help testing:
php script.php --help | less
Inspect Parsed Data Dump parsed options for debugging:
var_dump($parser->parse()->getOptions());
Check Raw Arguments
Access unparsed arguments via $parser->getArguments() before parsing. Since PHP 8 is now required, str_starts_with() / str_contains() are safe to use in any custom pre-filtering of $argv.
Error Messages Customize error messages for clarity:
$parser->setErrorMessage('Invalid option: %s');
Read the CI Badge, Not the Release Notes With GitHub Actions wired up (#17), a red badge usually means the maintainers pushed a change untested on some PHP version — a far better early-warning signal than the changelog text.
Custom Parsers
Extend Phalcon\Cli\OptionsParser to add:
Plugin System Use traits to add reusable option sets:
trait DatabaseOptions {
public function addDatabaseOptions(OptionsParser $parser): void {
$parser->addOption('host', 'H', 'Database host');
$parser->addOption('port', 'p', 'Database port');
}
}
Integration with Laravel While not native to Laravel, wrap the parser in a Laravel command — and note that with v2.0.0 you now share Laravel 9/10/11's PHP 8.0+ floor, so this is no longer a compatibility compromise:
use Phalcon\Cli\OptionsParser;
use Illuminate\Console\Command;
class MyCommand extends Command {
protected function handle() {
$parser = new OptionsParser();
// Parse and use options...
}
}
Prefer $this->argument() / $this->option() where Laravel already solves it; reach for the parser only for the richer help/validation surface.
Default Values Defaults are applied after parsing. To override:
$options = $parser->parse();
$options->setOption('timeout', 30); // Override default
Boolean Flags
Use true/false for flags (no value needed):
$parser->addOption('force', 'f', 'Force operation');
if ($options->getOption('force')) {
// Flag is true
}
Multi-Value Options Not natively supported. Use workarounds like:
php script.php --tags=tag1,tag2
Then split in PHP:
$tags = explode(',', $options->getOption('tags'));
Named Arguments vs. Option Names
PHP 8 named arguments make it tempting to spread parsed options into a constructor (new Job(...$options->toArray())). Option names containing dashes (--dry-run) or reserved words will blow up. Map explicitly, or expose a snake_case accessor on your DTO instead.
How can I help you explore Laravel packages today?