PHP CLI Development Introduction

PHP CLI Development Introduction

If you are not familiar with CLI, then this is the perfect introduction for you. In this tutorial, I will go over how to write command-line-driven PHP where you can hit an external API and parse results by simply typing a single command in your terminal. With CLI, you can give other non-developers a way to run your code with flags and variables that will be contained within 1 line in either CMD, Powershell, Terminal, or other command-line interfaces.

View This On YouTube

This tutorial is not in-depth by any means but should help you get started with exploring CLI and PHP development.

Code we will run in CLI:

php index.php {postID or NULL} {-c or NULL} {true or null|false}

Folder Structure

index.php
autoload.php
/src/Data.php

Setup Autoloader for Class

Since we will be using OOP for this tutorial, I am going to go ahead and set up our autoloader. This file will bring in our classes and methods to use on our index.php file. I have created a tutorial explaining this file in more detail previously. You can find it here if you would like more information:

autoload.php

<?php
spl_autoload_register(function ($class){
    $prefix = 'App\\';
    $base_dir = __DIR__ . '/src/';
    $len = strlen($prefix);

    if(0 != strncmp($prefix, $class, $len)) {
        return;
    }

    $relative_class = substr($class, $len);

    $file = $base_dir. str_replace('\\','/', $relative_class) . '.php';

    if(file_exists($file)) {
        require $file;
    }
});

Create index.php

To make everything work from CLI, we need to create a file to run the code. Essentially, we will be using the CLI command at the beginning of the tutorial so we need to make sure the index.php is available. You can use whatever file or route you want, but for this tutorial, we will be using the index.php for our main CLI file.

In this file, we will gather our CLI variables and pass them to the controller methods. This page is very important and needs to not only check for the existence of the variables but make sure they are passed in the correct format.

index.php

<?php
// php index.php {postID or null} {-c or null} {true or null|false}

use App\Data;

require_once 'autoload.php';

$postID = (isset($argv[1]) ? (int) $argv[1] : 0); // int
$displayComments = isset($argv[2]) && $argv[2] === '-c' ? true : false; // flag -> false
$displayArr = isset($argv[3]) && $argv[3] === 'true' ?: false; //bool

// test dump of variables
var_dump((new Data($postID, $displayComments, $displayArr))->displayData());

// send data to API
var_dump((new Data($postID, $displayComments, $displayArr))->getAPI());

Setup Data Controller

We will be using a simple dummy API to pull data from. It is free and you can use it to test out your code or you can change it to your own API.

In this class, we will be passing variables from our index.php CLI interface. We need to set up the variables and make sure they contain the correct data.

src/Data.php

<?php

namespace App;

class Data {

    /**
     * Post ID
     *
     * @var int
     */
    private $postID;

    /**
     * Display comments
     *
     * @var bool
     */
    private $displayComments;

    /**
     * Parse JSON as array or object
     *
     * @var bool
     */
    private $displayArr;

    public function __construct(int $postID = null, bool $displayComments, bool $displayArr){
        $this->postID = $postID;
        $this->displayComments = $displayComments;
        $this->displayArr = $displayArr;
    }

    /**
     * Sample function to display CLI data
     *
     * @return array
     */
    public function displayData(){
        return [
            'postID'=>$this->postID,
            'displayComments'=> $this->displayComments,
            'displayArr'=>$this->displayArr
        ];
    }

    /**
     * Send data to a sample API and return a response
     *
     * @return array|object
     */
    public function getAPI(){
        // setup API URL for the dummy "Blog" API
        $apiURL = 'https://jsonplaceholder.typicode.com/posts';

        // Modify the API URL if a post ID is added
        $postID = ($this->postID != 0 ? '/'.$this->postID : '');

        // Modify the API URL if comments are added
        $displayComments = ($this->displayComments ? '/comments' : '');

        // get the JSON from the API using file_get_contents
        $json = file_get_contents($apiURL.$postID.$displayComments);

        // either push API results as JSON or as PHP Array
        $res = ($this->displayArr === true ? json_decode($json, true) : $json);
        return $res;
    }
}

Conclusion

Now that you have all of the code for your CLI, you can run the following command in CMD, Powershell, Terminal or CLI of your choice:

php index.php {postID or NULL} {-c or NULL} {true or null|false}

Once you run it, if you are using my code, you should see results from the API. Either all blog articles or a single article with comments and either a JSON or Array format. Good luck and I hope this peaks your interest in CLI development.