PHP in the Dark: Layout (1): Helpers in PEAR
When you think of shell scripts, layout is the least of your worries. I think most of you would not even have considered you can do much in these field, but think again! In this first part we'll talk about organizing data in tables, write text in colors, create progressbars, etc... using pear classes.
You can find more information on this series, in the PHP in the Dark blog post.
This talk explains how to add color, tables and progress bars using PEAR classes. In a future post, we'll also see how to do this with EZ Component's ConsoleTools.
- Using Color: highlight text on the screen using text and background colors
- Tables: Structure data in a table
- Progressbars: inform the user of the scripts progress using progressbars
Using Color
It is possible to use color in your script, by adding special color escape sequences. These look like \033[01;31m which is the code for red text. As you can image this is not very user-friendly.
Luckily PEAR has a class that can help us out: Console_Color. It's easy to install if you have PEAR on your machine:
pear install Console_Color
The class contains several methods:
- convert: takes a string and converts the color/style codes inside to ANSI color escape sequence.
- color: you pass in foreground color, style and background color and it returns an ansi escape sequence.
- bgcolor: takes a color name and converts it to a background color escape sequence.
- fgcolor: takes a color name and converts it to a foreground color escape sequence.
- style: takes a color name and converts it to a style color escape sequence.
- escape: escapes every occurance of % to %% so it is not processed when converting.
- strip: strips all color escape sequences from a string.
note: I noticed that using the class results in a lot of notices (pun intended).
Bringing it together
Example script (01-console-color.php):
require_once 'Console/Color.php';
// color reset sequence, for later use
$reset = Console_Color::convert('%n');
// %r = RED
echo Console_Color::convert('Ratio %r0-30%%%n (low)') . PHP_EOL;
// get YELLOW
$yellow = Console_Color::fgcolor('yellow');
echo 'Ratio ' . $yellow . '31-70% ' . $reset . ' (average)' . PHP_EOL;
// %G = BOLD GREEN
echo Console_Color::convert('Ratio %G71-100%%%n (high)') . PHP_EOL;
// CYAN background, RED text, underlined
$style = Console_Color::color('red', 'underline', 'cyan');
echo $style . ' DONE? ' . $reset . PHP_EOL;
// BLACK background, CYAN text, underlined
$redbg = Console_Color::bgcolor('red');
$cyantxt = Console_Color::fgcolor('cyan');
$underline = Console_Color::style('underline');
echo $redbg . $cyantxt . $underline . ' YES! ' . $reset . PHP_EOL;
This gives following output:
./01-console-color.php Ratio 0-30% (low) Ratio 31-70% (average) Ratio 71-100% (high) DONE? YES!
Color & Style Codes
Console_Color makes use of a number of color and style codes that you can use and convert. They are easier to implement than the ansi color escape sequence. Each color has a code for normal, bold and background:
| Color | Normal | Bold* | Background |
|---|---|---|---|
| black | %k | %K | %0 |
| red | %r | %R | %1 |
| green | %g | %G | %2 |
| yellow | %y | %Y | %3 |
| blue | %b | %B | %4 |
| magento | %m | %M | %5 |
| cyan | %c | %C | %6 |
| white | %w | %W | %7 |
Apart from color codes, you can also apply different styles:
| Style | Code |
|---|---|
| flash/blink | %F |
| underline | %U |
| bold | %_,%9 |
| reverse | %8 |
| reset | %n |
| %% | single % |
If you want to see what all codes look like, you can run the script 02-console-all-colors.php. The result is something like this:
| black: | normal | bold | background |
| red: | normal | bold | background |
| green: | normal | bold | background |
| yellow: | normal | bold | background |
| blue: | normal | bold | background |
| magento: | normal | bold | background |
| cyan: | normal | bold | background |
| white: | normal | bold | background |
| underline | |||
| bold |
Tables
If you had a look at 02-console-all-colors.php you might have noticed I used spaces to format the data into a table. This is OK if you know upfront what the sizes are going to be, but when you have dynamic data that is less evident. I you want to add a title or borders, it becomes even more complex to do. PEAR has a class called Console_Table that can help us with this. To install it:
pear install Console_Table
The basics
The concept is quite easy: you set your headers, you add your data and you render the table. A quick example (03-console-table.php):
require 'Console/Table.php';
$tbl = new Console_Table();
$tbl->setHeaders(
array('Language', 'Year')
);
$tbl->addRow(array('PHP', 1994));
$tbl->addRow(array('C', 1970));
$tbl->addRow(array('C++', 1983));
$data = array(
array('MySQL', 1994),
array('CouchDB', 2005),
array('Oracle', 1978)
);
$tbl->addData($data, 0, 3);
echo $tbl->getTable() . PHP_EOL;
This results in a table looking like this:
./03-console-table.php +----------+------+ | Language | Year | +----------+------+ | PHP | 1994 | | C | 1970 | | C++ | 1983 | | MySQL | 1994 | | CouchDB | 2005 | | Oracle | 1978 | +----------+------+
Filters
Console_Table allows you to define filters using callback handlers and attach these to a column. Suppose you want all unknown values replaced by N/A, you could do something like this:
// Call back function
function checkNA($value) {
$value = trim($value);
if (empty($value) || $value == '?') {
return 'N/A';
}
return $value;
}
// Create a new table and define the headers
require '../Library/Console/Table.php';
$tbl = new Console_Table();
$tbl->setHeaders(
array('Title', 'Author', 'Published')
);
// Add the filter to the second and third column
$func = 'checkNA';
$tbl->addFilter(1, $func);
$tbl->addFilter(2, $func);
// Add the data
$data = array(
array('Ghosts', '?', 1981),
array('Origins', 'S. Ome D. Ude', ''),
array('My Book', 'Jeroen', 2050)
);
$tbl->addData($data);
// Print the table
echo $tbl->getTable() . PHP_EOL;
When you execute this script (04-console-table-filters.php), you get an output like this:
./04-console-table-filters.php +---------+---------------+-----------+ | Title | Author | Published | +---------+---------------+-----------+ | Ghosts | N/A | 1981 | | Origins | S. Ome D. Ude | N/A | | My Book | Jeroen | 2050 | +---------+---------------+-----------+
Progressbars
When you're script is running, it's always nice to provide some feedback to the user. If you know the amount of work that needs to be done, you can use a progressbar to inform the user of how much work is still left to do. Progressbars are easy to do with PEAR's Console_ProgressBar. Have a look at the next example (05-console-progressbar.php):
require 'Console/ProgressBar.php';
$format = '[%bar%] %percent% (%current%/%max%) ';
$filler = '=>';
$empty = ' ';
$width = 70;
$size = 140;
$bar = new Console_ProgressBar($format, $filler, $empty, $width, $size);
for ($i = 0; $i <= $size; $i++) {
$bar->update($i);
sleep(1);
}
The result of this is something like this:
[> ] 0.00% (0/140)
Conclusion
In this blog post we saw a couple of PEAR classes that can help us creating more interesting output: Tables, Colors and Progressbars.
In the next 3 blog posts, I will talk about EZ Component's ConsoleTools, ncurses and newt. Ncurses and newt are 2 *nix terminal libraries that will allow you to create interactive shell user interfaces.
Resources
The code examples for this article can be found on GitHub. If you want to execute them, you will have to make them executable (chmod +x) or pass them to php (php some-script.php).
https://github.com/Amazium/PHP-In-The-Dark/tree/master/2-Layout






+32 475 62.42.64