Box drawing in PHP
Back in the “good old days” of MS-DOS, you could draw lines, boxes, filled areas (think progress bars), and more using the extended ASCII character set (AKA code page 437).
While writing a simple command-line utility in PHP I wanted to use the full block (█) and light shade (░) characters to create a simple progress bar that is a bit nicer than the typical =========....................
Like this:
█████████████████░░░░░░░░░░░░░░░░░░░░░░░ 42.5%
Instinctively, I turned to PHP’s chr() function and looked up the extended ASCII codes for the characters I needed. Boy, was I disappointed when my progress bar was nothing but a series of un-useful question marks. Surely PHP can render simple ASCII characters, I thought.
It might have gone differently if I had been using a PC, but I do 100% of my development these days on a Macbook Pro. It so happens that the bash shell in UNIX, Linux, and Mac OS X all use UTF-8 encoding by default, not CP437. (Of course, your terminal font will need to support UTF-8 characters for this to work.)
So, I just needed to find the UTF-8 codes for the characters I needed and use those instead of the old familiar CP437 ones. However, the results weren’t much better.
After an hour or more of Googling and experimentation, I finally realized that chr() doesn’t do UTF-8. I found various suggestions on how to produce the desired characters using custom functions and the like, but the best way turned out to just use a good ‘ol HTML entity and run it through html_entity_decode:
$block = html_entity_decode('█', ENT_NOQUOTES, 'UTF-8'); // full block
$shade = html_entity_decode('░', ENT_NOQUOTES, 'UTF-8'); // light shade
Now, a progress bar isn’t exactly a box, so let’s demonstrate:
$tl = html_entity_decode('╔', ENT_NOQUOTES, 'UTF-8'); // top left corner
$tr = html_entity_decode('╗', ENT_NOQUOTES, 'UTF-8'); // top right corner
$bl = html_entity_decode('╚', ENT_NOQUOTES, 'UTF-8'); // bottom left corner
$br = html_entity_decode('╝', ENT_NOQUOTES, 'UTF-8'); // bottom right corner
$v = html_entity_decode('║', ENT_NOQUOTES, 'UTF-8'); // vertical wall
$h = html_entity_decode('═', ENT_NOQUOTES, 'UTF-8'); // horizontal wall
echo $tl . str_repeat($h, 15) . $tr . "\n" .
$v . ' Hello, World! ' . $v . "\n" .
$bl . str_repeat($h, 15) . $br . "\n";
Voilà!
UTF-8, once you get used to it, actually provides many more possibilities than CP437 did back in the MS-DOS days. Enjoy!