Codementor Events

How to Build a Lightweight Command Runner for the CLI using PHP

Published Jul 12, 2016Last updated Apr 12, 2017
How to Build a Lightweight Command Runner for the CLI using PHP

As most programmers are aware, there are large amount of tasks that need to be completed. To combat wasted time, there are a number of popular task runners. Task runners do just that: execute a task that has been provided.
Two popular task runners are gulp and grunt.
With the amount of time saved by automating some processes is a huge benefit.

With that in mind, let's write our own command runner using PHP 7. Why PHP 7? The performance of shell scripts using PHP 7 is far superior to that of the 5.x branches.

Step 1: Base Class

abstract class PHPCommandRunner 
{
    abstract function onUnhandled($command);
    
    public function processArguments($argc, $argv)
    {
        //were there enough args passed from the command line?
        if ($argc <= 1) { 
            echo "Not enough arguments.\n";
            exit(1);
        }
        //get the task name, then calculate the name of the method to call,
        //for example, "onSaveCommand".
        for($i = 1; $i<$argc; $i++) {
        $commandName = $argv[$i];
        $methodName = "on".ucfirst(strtolower($commandName))."Command";

        //if the method exists in the class implementation, call it, otherwise
        //it's unhandled.
        if (method_exists(Static::class, $methodName)) {
            call_user_func_array(array(Static::class, $methodName), ['name'=>$commandName, 'runner'=>$this]);
        } else {
            $this->onUnhandled($commandName);  //valid command name, but no handler specified.
        }
        }
    }
    
    public function run($argc, $argv)
    {
    $argv = $this->processArguments($argc, $argv);
    print_r($argv);
    }

}

That's it! Now all we need to do is write a class that extends the base PHPTaskRunner class, and add some command handler methods:

Step 2: Implementation

class MyCommandRunner extends PHPCommandRunner 
{
    public function onUnhandled($command)
    {
        echo "No handler defined for command '$command`.\n";
        return true;
    }

    //handle the "hello" command
    public function onHelloCommand($args)
    {
        echo "Hello, world!\n";
        return true;
    }
    
    //handle the "goodbye" command
    public function onGoodbyeCommand($args)
    {
        echo "Goodbye, world!\n";
        return true;
    }
}

Step 3: Putting it together

demo.php:

<?php
  require('PHPCommandRunner.php');
  require('MyCommandRunner.php');

  $tr = new MyCommandRunner("test");
  $tr->run(count($args), $argv);

Finally, run php demo.php hello goodbye on the command line.
You'll see output like:

- Hello, world!
- Goodbye, world!--
Discover and read more posts from Patrick
get started