Skip to content

Instantly share code, notes, and snippets.

@jakejohns
Created May 23, 2017 23:35
Show Gist options
  • Save jakejohns/1d24925c1b4d4cfb53486d709ba5e3e3 to your computer and use it in GitHub Desktop.
Save jakejohns/1d24925c1b4d4cfb53486d709ba5e3e3 to your computer and use it in GitHub Desktop.
Simple PHP Console
<?php
// @codingStandardsIgnoreFile
class Console
{
/**
* Available Commands
*
* Key i command name, value is callable spec
*
* @var array
*
* @access protected
*/
protected $commands = [];
/**
* Resolves a spec to a calable
*
* @var callable
*
* @access protected
*/
protected $resolver;
/**
* Name of executable
*
* @var string
*
* @access protected
*/
protected $executable;
/**
* Name of command
*
* @var string
*
* @access protected
*/
protected $command;
/**
* Arguments to pass to command
*
* @var array
*
* @access protected
*/
protected $args = [];
/**
* Constructor
*
* Create a new Console application
*
* @param array $commands available commands
* @param callable $resolver optional resolver
*
* @access public
*/
public function __construct(
array $commands,
callable $resolver = null
) {
$this->commands = $commands;
$this->resolver = $resolver;
}
/**
* Invoke a command
*
* Invoke a command by name with argv
*
* @param array $args should be argv probably
*
* @return bool
*
* @access public
*/
public function __invoke(array $args)
{
$this->init($args);
if (! $this->isValid()) {
$this->usage();
return false;
}
return $this->execute();
}
/**
* Initialize
*
* Setup state based on argv
*
* @param array $args input arguments
*
* @return null
*
* @access protected
*/
protected function init(array $args)
{
$this->executable = array_shift($args);
$this->command = array_shift($args);
$this->args = (array) $args;
}
/**
* Is Command valid?
*
* Check if input was valid
*
* @return bool
*
* @access protected
*/
protected function isValid()
{
return (null !== $this->command)
&& array_key_exists($this->command, $this->commands);
}
/**
* Actually execute command
*
* @return mixed
*
* @access protected
*/
protected function execute()
{
$spec = $this->commands[$this->command];
$command = $this->resolve($spec);
return call_user_func_array($command, $this->args);
}
/**
* Resolve spec
*
* @param mixed $spec spec to resolve to callable
*
* @return callable
*
* @access protected
*/
protected function resolve($spec)
{
if (! $this->resolver) {
return $spec;
}
return call_user_func($this->resolver, $spec);
}
/**
* Print usage
*
* @return null
*
* @access protected
*/
protected function usage()
{
echo 'Usage:' . PHP_EOL;
foreach (array_keys($this->commands) as $command) {
echo $this->executable . ' ' . $command . PHP_EOL;
}
}
}
#!/usr/bin/env php
<?php
// @codingStandardsIgnoreFile
/**
* Some Commands
*/
class HelloWorld
{
public function __invoke($name = 'World')
{
echo "Hello $name" . PHP_EOL;
return true;
}
}
class ByeWorld
{
public function __invoke($name = 'World')
{
echo "Bye $name" . PHP_EOL;
return true;
}
}
/**
* Simple resolver
*/
$resolver = function ($spec) {
return new $spec;
};
/**
* Create an application
*/
$console = new Console(
[
'hi' => HelloWorld::class,
'bye' => ByeWorld::class
],
$resolver
);
// Execute based on input and exit
$console($argv) ? exit(0) : exit(1);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment