Back to the module list

Console Power

The console class allow to interact with the user. It request data from line, display or hide the requested text. It also manage an optional historical of the commands.

It is based on readline feature.

Basic Usage

Get a command from the user :

$console = new console ();
$console->clearScreen (); // Not mandatory
$console->echo ("PRéééOMPT $i> ");
$line = $console->readline ();
echo "---->'$line'\n";

Request a password to the user

The password typed will not be displayed on screen

$console = new console ();
$console->echo ("Login: ");
$login = $console->readline ();
$console->echo ("Password: ");
$console->unsetEcho ();
$password = $console->readline ();
$console->setEcho ();
echo "Login=$login, Password=".str_repeat ("*", mb_strlen ($password))."\n";

Manage the history of the typed commands

The typed command from the user is stored in the history file to be retreive next time. The user can use the up and down arrows to navigate on the history.

$console = new console ();
$console->readHistory ("/tmp/history");
$console->historyMaxSize (5);
$console->echo ("PRéééOMPT $i> ");
$line = $console->readline ();
echo "---->'$line'\n";
$console->addHistory ($line);
$console->writeHistory ("/tmp/history");

The developper can get the history with :

print_r ($console->getHistory ());

In this case, the key is the timestamp of record and the value the command.

Propose the completion of the command

The user can type the TAB key to display the available commands. These commands are provide by an external function. If there is no answer, nothing is proposed.If there is multiple answers, all the possibilities are displayed.
The external function must return an array. It can be associative array, the keys are the allowed answers and the values are the help to the user. If the array is an iterative array, the value is the allowed answers.

function call ($string)
{
  $pos = strrpos ($string, " ");
  if ($pos === false)
    $lastword = $string;
  else
    $lastword = substr ($string, $pos + 1);
  return array ("Line" => "Only one line is allowed",
                "Word" => "The part of a sentence is a word",
                "Char" => "Each char is important");
}
$console = new console ();
$console->completeFunction ("\t", "call");
$console->echo ("PRéééOMPT $i> ");
$line = $console->readline ();
echo "---->'$line'\n";

Catch the Ctrl+C

The Ctrl+C stops the PHP execution by default.
If the program must catch the Ctrl+C user action, the developper can add after the $console instanciation :

exec ("stty intr ^J");

The readline will return "" if the user has pressed Ctrl+C and not close the PHP interpreter.

Window resizing

If the user change the window size, the calculations to redraw the lines will have some problem and will display some cut lines to the user. To avoid this, the developper can use the following code. Each time the window is resized, the console is informed of that and manage correctely the updated lines.

$console = new console ();
declare(ticks = 1);
pcntl_signal (SIGWINCH, function () use ($console) {
  $console->updateTerminalSize ();
});

Colors

Manage the colors of the text or the background Colors

$console->colorText (3);
$console->colorBackgroundText (7);

Font underline or bold

It is also possible to display text in bold or underline with

$console->textBold (true);
$console->textUnderline (true);

Complete example

And all in one file :

function call ($string)
{
  $possibilities = array (
    "cat" => "Read a file to display",
    "cat /etc/passwd" => "Read /etc/passwd to display",
    "cat /etc/group" => "Read /etc/group to display",
    "clear" => "Clear screen",
    "exit" => "Exit from the console",
    "logout" => "Exit from the console",
  );

  $res = array ();
  // Look for valid possibilities
  foreach ($possibilities as $key => $help)
  {
    if (mb_substr ($key, 0, mb_strlen ($string)) === $string)
      $res[$key] = $help;
  }
  // Remove the possibilites the words until the last one
  foreach ($res as $key => $help)
  {
    unset ($res[$key]);
    $pos = mb_strrpos ($key, " ");
    if ($pos !== false)
      $newkey = mb_substr ($key, 1 + mb_strrpos ($key, " "));
    else
      $newkey = $key;
    $res[$newkey] = $help;
  }
  $res = array_keys ($res);
  return $res;
}

$console = new console ();
// Catch the Ctrl+C
exec ("stty intr ^J");
// Manage the window resizing
declare(ticks = 1);
pcntl_signal (SIGWINCH, function () use ($console) {
  $console->updateTerminalSize ();
});
$console->clearScreen ();
$console->echo ("Login: ");
$login = $console->readline ();
$console->echo ("Password: ");
$console->unsetEcho ();
$password = $console->readline ();
$console->setEcho ();
echo "Login=$login, Password=".str_repeat ("*", mb_strlen ($password))."\n";
// The authentication is done, load the history if exists
$console->readHistory ("/tmp/history");
$console->historyMaxSize (5);
$console->completeFunction ("\t", "call");
while ($i < 5)
{
  $console->echo ("PRéééOMPT $i> ");
  $i++;
  $line = $console->readline ($propo);
  $propo = "";
  //echo "---->'$line'\n";
  $line = trim ($line);
  if ($line === "")
    continue;
  $console->addHistory ($line);
  $console->writeHistory ("/tmp/history");
  if ($line === "exit" || $line === "logout")
    exit;
  $propo = "";
  if ($line === "cat /etc/passwd")
  {
    echo file_get_contents ("/etc/passwd");
  }
  elseif ($line === "clear")
  {
    $console->clearScreen ();
  }
  elseif ($line === "history")
  {
    print_r ($console->getHistory ());
  }
  else
  {
    echo "Command not found\n";
  }
}

The class definition

Class \console

Namespace \

Description

 Allow to manage a linux Console to have a minimal but working text interface
 When using this class, you must use the $console::echo method and not
 display directely on screen
 Like readline, but all in PHP
 Manage the historical of the provided commands
 Allow the user to use arrow keys and the shortcuts Ctrl+arrow, Ctrl+L,
 Ctrl+U, Ctrl+W
 To not allow the stop of the program by Ctrl+C, you can add
     exec ("stty intr ^J");
 To update the window size when the terminal is resized, use after console
 instanciation :
     declare(ticks = 1);
     pcntl_signal (SIGWINCH, function () use ($console) {
       $console->updateTerminalSize ();
     });

Properties

No property available

Methods

public function __construct ()
 The constructor init the console.
 Check if we have the rights to execute, if wa have in cli...

public function __destruct ()
 The destructor return the terminal to initial state

public function addHistory ( $line)
 Add a new entry in history.
 The new line can not be empty : it is not stored, but without error
 This method do NOT write the history on disk : you must use writeHistory
 @param string The new entry to add in history

public function clearHistory ()
 Clear the history
 This method do NOT write the empty history on disk

public function clearLine ()
 Clear the existing line.

public function clearScreen ()
 Clear all the screen and remove the scroll of the screen

public function colorBackgroundText ( $colorNum)
 Set the background text color
 @param integer $colorNum The color number to use

public function colorReset ()
 Reset the colors

public function colorText ( $colorNum)
 Set the text color
 @param integer $colorNum The color number to use

public function completeFunction ( $completionKeys, $completionFunction)
 Call a specific function when a completion key is pressed
 @param string|bool $completionKeys The list of the completion keys. False
 unset the method
 @param callable $completionFunction The function called when one of the
 completion keys is pressed.
 The function must get the partial text as first parameter, and must return
 an array with the possibilities

public function consoleException ( $message)
 Error management
 @param string $message The message to throw in the exception

public function echo ( $message)
 Display a text on screen. Must be used before "readline" method because
 the provided message will not be deleted by readline process.
 @param string $message The message to display

public function getHistory ()
 Get the actual history in memory

public function getKey ()
 Wait one key pressed by the user. If the key pressed is an ESC sequence,
 return this sequence
 The non printable chars are not displayed, but are correctely returned
 The UTF8 chars are return as multiple length chars
 @return the pressed char

public function getc ()
 Wait one valid character from the user.
 The non printable chars are not displayed, nor returned
 The ESC Sequences are skipped
 @return the pressed char

public function historyMaxSize ( $historyMaxSize=null)
 Get/Set the maximum number of entries in the history
 If null, get the defined maximum number
 @param integer|null $historyMaxSize The maximum number of entries

public function readHistory ( $historyFile)
 Read the history from the disk
 If the file doesn't exists, return an empty array
 @param string $historyFile The history file where the history is stored
 @return the read history with timestamp as key and command as value

public function readline ( $propo="", $stopperChar=false)
 Get the line of characters pressed by the user and return the result.
 Stop when the user valid by \n.
 Manage correctely the backspace, the Ctrl+W to remove word...
 @param string $propo Preset the text for the user
 @param boolean|string $stopperChar The chars to stop the analysis and
 return the result
 @return The typed string

public function setEcho ()
 Each time a key is pressed by the user, display the value on screen (echo)

public function textBold ( $bold)
 Bold the text
 @param boolean $bold True to bold, false to remove the bold

public function textUnderline ( $underline)
 Underline the text
 @param boolean $underline True to underline, false to remove the underline

public function unsetEcho ()
 Each time a key is pressed by the user, DO NOT display the value on screen
 (echo disabled)

public function updateTerminalSize ()
 Update the terminal size

public function writeHistory ( $historyFile)
 Write the history to disk.
 @param string $historyFile The history file where the history is stored