Tag Archives: ubuntu

Ncurses and PHP I

Back to the 2005 I did a course on Linux administration and we over saw a bit of Ncurses.

Ncurses is the open implementation of Curses which is a library that provides functionalities to draw the screen, keyboard and mouse management in terminals in text mode regardless of the terminal type.
This is that there are terminals with colours or only 2 colours, different number of columns and rows, character set as well as keyboard and mouse functionalities. Ncurses takes care of all for us.

Formulario de instalación de Linux (wikipedia)

Ncurses is develop in C but there are interfaces to access its functionalities from other languages like Python, Perl, JavaScript, PHP and many others.

I work with PHP which is a language mainly for web development and I thought it was interesting to be able to use it for something else other than the web and I remembered this library so I decided to research about it and see what we can do with PHP and Ncurses.

In the lists of commands I’ll give below I assume that with work with a fresh Ubuntu installation and that we have to install all the dependencies fro scratch as well as we are super user.

Installing Ncurses in PHP5.6

The reason is that the Ncurses extension wasn’t ported to PHP7 but there is a way to install it that I’ll explain later.

The ncurses extension for php isn’t available in APT but in PECL so we need to install it first.

  1. apt-get update
  2. apt-get -y install software-properties-common
  3. add-apt-repository ppa:ondrej/php
  4. apt-get update
  5. apt-get -y install php5.6-dev php5.6-xml libncurses5-dev libncursesw5-dev
  6. pecl install ncurses
  7. echo "extension=ncurses.so" > /etc/php/5.6/cli/conf.d/20-ncurses.ini

Now we can check that it’s installed with the following command:

php -m | grep ncurses

Installing Ncurses in PHP.7

n PHP 7 the process has more steps because because if we tried to install Ncurses with PECL, at step 6 it would give error. Instead we are going to download it and apply a patch by hand.

  1. apt-get update
  2. apt-get -y install wget php-dev libncursesw5-dev libncurses5-dev php-pear
  3. cd /root
  4. pecl download ncurses
  5. mkdir /root/ncurses
  6. cd /root/ncurses
  7. tar -xvzf /root/ncurses-1.0.2.tgz
  8. wget "https://bugs.php.net/patch-display.php?bug_id=71299&patch=ncurses-php7-support-again.patch&revision=1474549490&download=1" -O ncurses.patch
  9. mv ncurses-1.0.2 ncurses-php5
  10. patch --strip=0 --verbose --ignore-whitespace <ncurses.patch
  11. cd ncurses-php5
  12. phpize
  13. ./configure
  14. make
  15. make install
  16. cat <<'EndOfHereDoc' >/etc/php/7.2/mods-available/ncurses.ini
    ; configuration for php ncurses module
    ; priority=20
    extension=ncurses.so
    EndOfHereDoc
  17. ln --symbolic /etc/php/7.2/mods-available/ncurses.ini /etc/php/7.2/cli/conf.d/20-ncurses.ini
  18. php -m | grep ncurses

Sample code:

Here I leave a PHP script that draws a frame in the middle of the screen with the phrase hola mundo.

#!/usr/bin/env php
<?php
/*
 * We force this environment variable to “linux because in some terminals
 * the border that we are going to use to draw the dialogue box doesn’t
 * show well in Putty nor in colour without this value.
 */
putenv('TERM=linux');

//Iniciamos ncurses.
$ncurses_session = ncurses_init();

//We save the settings there were before running the script
ncurses_savetty();

//we check whether the terminal is in colour.
if (ncurses_has_colors()) {
    ncurses_start_color();
	//we create an ink and paper colour combination.
    ncurses_init_pair(
		1,						//index
		NCURSES_COLOR_YELLOW,	//ink colour
		NCURSES_COLOR_BLUE		//papel colour
	);
	//we set this colour by default.
    ncurses_color_set(1);
}
/**
 * we createe "window" with the values 0.
 * This creates a "window" of the size of the screen.
 * The window is a concept that will be explained.
 */
$ventana_principal = ncurses_newwin(
	0, //rows
	0, //columns
	0, //y
	0  //x
);

//We use the window to capture the size in columns and rows by reference.
ncurses_getmaxyx($ventana_principal, $filas, $columnas);

//We create an smaller window to draw inside.
$my_windows = ncurses_newwin(
	5,	//rows
	15,	//columns
	($filas - 5) / 2,		//y
	($columnas - 15) / 2	//x
);

//we set the same colour we created above to draw in the window.
ncurses_wcolor_set($my_windows , 1);

/*
 * the loop is to paint the background of the window
 * we paint 5 rows of spaces of blue colour
 */
for($y = 0; $y < 5; $y++){
	//We set the cursor on the corresponding row.
	ncurses_wmove($my_windows , $y, 0);
	//We paint a 15 space character line.
	ncurses_whline(
		$my_windows ,	//handler of our window.
		ord(' '),		//Chracter we are going to draw. It has to be converter indo ASCII.
		15
	);
}

//now we write the text of our window.
ncurses_mvwaddstr(
	$my_windows ,	//handler of our window.
	2,				//y, relative to the interior of our window.
	3,				//x, relative to the interior of our window.
	'Hola mundo'	//text
);

//now we draw the frame around.
ncurses_wborder(
	$my_windows ,	//handler of our window.
	0, //character to paint line on the left, 0 =│, ord('|') for another
	0, //character to paint line on the right, 0 =│, ord('|') for another
	0, //character to paint line on the top, 0 = ─, ord('-') for another
	0, //character to paint line on the bottom, 0 = ─, ord('-') for another
	0, //character to paint corner top-left 0 = ┌, ord('+') for another
	0, //character to paint corner top-right 0 = ┐, ord('+') for another
	0, //character to paint corner bottom-left 0 = └, ord('+') for another
	0  //character to paint corner bottom.right 0 = ┘, ord('+') for another
); // border it

//now we flush on the screen the window we draw above.
ncurses_wrefresh($my_windows);

//we reset the settings there were before we run the script
ncurses_resetty();
//we close ncurses
ncurses_end();

Copy and paste this script in a file called test.php and run it with the following command:

php test.php

It should look like this:

I hope you find it interesting.