Zend Developer Zone
Where the ElePHpants come to learn

Zend Developer Zone

Using Ncurses in PHP

Incredibly Old Content Warning!

The content you are viewing is more than three years old. It is here for archival purposes. Do not use any advice in this article.

::Jedi Hand Wave:: This is not the information you are looking for. Move along.

Intended audience


Learning Objectives


Background Information


How it Works

Putting it all together

The Script



About the author

Intended audience

This tutorial is intended for expert PHP
programmers interested in extending command-line PHP applications to generate
terminal-based user interfaces. You need SSH access to a UNIX server with PHP 4
compiled with ncurses.


As a programmer you are often assigned to write programs for
system administration tasks. By default, command line applications in PHP lack
aesthetics. By taking advantage of the
ncurses functions you can create a
friendly user interface for the application that will be generally uniform
across the various terminal types.

PHP is a highly flexible and extensible language and can be used to augment your
existing shell/Perl scripting solutions or replace them; so ncurses
functionality is a natural progression for PHP.

This tutorial will give you a kick-start towards writing decent looking command-line
applications that benefit the user as well as the writer. I will focus on the
‘meat’ of what is needed and hopefully give you a framework for adding
ncurses functionality into your PHP application.

Learning Objectives

In this tutorial you will:

  • Learn how to create basic
    windows using ncurses and PHP, and write data to
  • Learn how to
    create ncurses window sets in PHP, and dynamically size the windows to fit the
  • Learn the
    specifics of window handles, and how to capture function
  • See an example
    of using the ncurses functions by creating a small application that extends the
    Linux traceroute program while using all the functions discussed


  • Ncurses : The
    Ncurses (new curses) library is a free software emulation of curses in System V
    Release 4.0, and more. It uses Terminfo format, supports pads and color and
    multiple highlights and forms characters and function-key mapping, and has all
    the other SYSV-curses enhancements over BSD Curses. If you have used Linux you
    have probably seen ncurses in action. Programs such as Midnight commander,
    ncftp, Iptraf, trafshow and many others use ncurses for the visual aspect of the
  • Window:
    The term ‘window’ as used in this document refers to a section
    of a terminal that is created via ncurses in

Background Information

This tutorial is written for the advanced programmer.

It has been said that the Curses library of functions is appropriately named.
The documentation for the PHP ncurses functions is very limited and several of
the functions used in this tutorial do not even appear on the php.net website
as of this writing. Ncurses applications follow a c-style format, as they are
written to be true applications and not simply scripts with a defined start and

If you have experience programming in C or C++ then you are probably already familiar
with what ncurses can do, and can probably imagine how useful ncurses can be when
used in conjunction with a scripting language like PHP.


You will need to have access to PHP compiled with –with-ncurses on a Unix-based
system. Not all terminals will support colorized ncurses output so this tutorial
will not use any coloring functions.

Keep in mind that you might have to reset your terminal often while working with
ncurses. If you have an error ncurses_end() is not called, so your
terminal will be fried and you will have to issue the ‘reset’
command to fix it.

Order is also very important for these functions, you can segfault PHP by attempting
to refresh a window that does not have an appropriate resource handle.

How it Works

Using ncurses we will create a functional window system and increase interface

Lets start with a very basic ncurses introduction before moving into anything
more advanced:

First let’s create an ncurses main window that uses the entire screen region
it has available. Then let’s add in a smaller window into the middle of
this screen and write a string to it. It will look like this.

Start ncurses with
which lets PHP know that you wish to enter into ncurses mode. Without making a
call to
before calling ncurses functions, PHP will error.

The code to produce the above


// we begin by initializing ncurses

$ncurse ncurses_init();

// let ncurses know we wish to use the whole screen

$fullscreen ncurses_newwin 0000); 

// draw a border around the whole thing.


// now lets create a small window

$small ncurses_newwin(1030725);

// border our small window.


ncurses_refresh();// paint both windows

// move into the small window and write a string

ncurses_mvwaddstr($small55"   Test  String   ");

// show our handiwork and refresh our small window


$pressed ncurses_getch();// wait for a user keypress

ncurses_end();// clean up our screen


Try resizing the terminal and running
the code again. Notice that the main window will border itself using the maximum
values for the height and width.

Now you may want to see something
actually happen when you press a key, or you may not want to exit the
application unless a certain key is pressed. I personally prefer using the
escape key (char(27)) for this. To do this, at the top of the script add



    ... #code


to read

If($pressed == ESCAPE_KEY){






Now if you press any key except
Escape, its integer equivalent will be placed within the window resource named
“small”. This creates a little application that responds to key
presses and exits only when you press Escape.

We can make this look better by adding a title-bar.


ncurses_mvaddstr(0,1,"My first ncurses application");


You are not just limited to using
either; you can use DIM,
as well as several

To add intuitive usability to a program
you will want to add a menu system.

Most programs have user interaction and the ability to select menu items. In the
past we used number or alpha systems where the user would select which menu item
he wanted by typing a number or letter on the keyboard and the item would be selected.
Selection menus have been replaced by interactive menu systems. You want to have
a menu that visually signals the user as to which option is currently selected.

The following code will replace
“$pressed =
in the previous

$menu = array("one","two","three","four");


$out $menu[$a];

        if($currently_selected == intval($a)){ 


ncurses_mvwaddstr ($small1+$a1$out);



ncurses_mvwaddstr ($small1+$a1$out);



ncurses_wrefresh($small); // otherwise we will not see

  $pressed ncurses_getch($lower_main_window); // wait for user to press key

if($pressed == NCURSES_KEY_UP){


$currently_selected 0){ $currently_selected 0; }

$pressed == NCURSES_KEY_DOWN){


$currently_selected >= count($menu)){ $currently_selected count($menu)-1; }

  }elseif( $pressed == ESCAPE_KEY){






When run you will have an
application that looks like the following illustration. It has a menu that you
can navigate through using the arrow keys and exits when you press

Now that you have this knowledge of
ncurses you are probably thinking of all kinds of applications that you can
create that utilize these functions. So the next portion of this tutorial will
focus on using ncurses to create a real world application that is both useful
and an excellent starting point for further development.

Putting it all together

The online documentation for PHP currently has 119 listed functions for ncurses;
the following list contains the functions used in the script below with links
to the online documentation where available. The four functions listed below which
do not appear in the online documentation are explained.


Initialize ncurses.


Create a new window.

ncurses_getmaxyx( resource window, int
return Y, int return X);

Sets Y and X to maximum size of current


Draw a border around the main


Refresh the main window; use
ncurses_wrefresh for refreshing individual windows.


Turn output attribute


Move and insert a


Turn output attribute

ncurses_wborder (resource window, int
left, int right, int top, int bottom, int tl_corner, int tr_corner, int
bl_corner, int br_corner);

Identical to ncurses_border except that you pass the window resource as an additional first parameter.

ncurses_wattron(resource window, int

Identical to ncurses_attron except that you pass the window resource as an additional first parameter


Select a window and place a string
within it a coordinates.

ncurses_wattroff (resource window, int

Identical to ncurses_attroff except that you pass the window resource as an additional first parameter.


Refresh named window


Wait for user keyboard or mouse

The Script

The following code will produce a window which looks like this:

This script runs a traceroute to
zend.com, limits the hops to only ten, and displays
the results within a window. The items in the upper window are scrollable by
using your arrow keys and when you press Enter on each one a reverse
whois is
done and the results are placed in the lower window. If you press the escape key
the program will exit.


// define some key constants.



// get our initial data

$tr_return traceroute("www.zend.com");

$ncurses_session ncurses_init();

$main ncurses_newwin(0000); // main window




// border the main window


ncurses_mvaddstr(0,1,"Traceroute example");


 // create a lower window which is dynamically sized...

$lower_frame_window ncurses_newwin (10$columns-3$lines-111);

        ncurses_wborder($lower_frame_window0,00,00,00,0); // border it

        $lower_main_window ncurses_newwin (8$columns-5$lines-102);

        $main_list_window ncurses_newwin ($lines-12$columns-311);

ncurses_wborder($main_list_window0,00,00,00,0); // border it

  if($currently_selected == ""){$currently_selected 0;}


        $out $tr_return[$a];

$currently_selected == intval($a)){ 


            ncurses_mvwaddstr ($main_list_window1+$a1$out);



ncurses_mvwaddstr ($main_list_window1+$a1$out);



$y == ENTER_KEY){    

        $newout explode(" "$check_me);

$rwhois_return rwhois(trim($newout[3]));



ncurses_mvwaddstr($lower_main_window1+$a1$key " - " $val);



$y == ESCAPE_KEY){




ncurses_move(-1,1); // toss cursor out of sight.


ncurses_wrefresh($lower_main_window); // show it


  // wait for user to press a key

  $y ncurses_getch($lower_main_window);

  // check for the presence of up-arrow and down-arrow keys

if($y == NCURSES_KEY_UP){


$currently_selected 0){ $currently_selected 0; }

  }elseif( $y == NCURSES_KEY_DOWN){


$currently_selected >= count($tr_return)){ $currently_selected count($tr_return)-1; }


}//end main while

// the following are two helper functions for

// this ncurses example.

function traceroute($address){

exec("/usr/sbin/traceroute -x -n -m 10 $address",



//end function

// reverse whois

function rwhois($query){

$fp fsockopen ("rwhois.arin.net"4321$errno$errstr30);

    if (!$fp) {

$ret[] = "$errstr ($errno)\n";


fputs ($fp"$query\r\n\r\n");


            while (!
feof($fp) && $count 17) {

$back fgets ($fp,128);

            $data explode(":",$back);

$ret[$data[1]] = $data[2];



fclose ($fp);


return $ret;

//end function



The code above is obviously a very simple framework for an ncurses application.
With so many functions at your disposal there is quite a world of interfaces that
can be developed.

This tutorial has not touched upon using the mouse in terminals, using colors
or many of the output control functions and their defined constants.

You will want to create a library of functions for using ncurses for doing things
like starting up ncurses and returning a handle to the main window or for drawing

The following are two functions which
show in more depth how to use the
function and how to create dynamically sized
windows within terminal screens. These will be a good start for much more
advanced functions. These can easily be extended to add in title bars, panes or
anything else you can think up.


# left_window(int size) creates an ncurses window

# that is write-safe on the left-hand side of the

# screen $size is how wide it will be

# returns window handle of inner window.


function left_window($size=15){

    global $fullscreen;


    $c ncurses_newwin ($MAX_Y-,$size11);

    ncurses_wborder($c,0,00,00,00,0); // border it

// now create window overtop the other just

// slightly smaller so that we won't write over

// the border.

$d ncurses_newwin ($MAX_Y-,$size-21+12);

    ncurses_wrefresh($c); // show it





# creates an upper-right window


function upperr_window($size=15){



    $c ncurses_newwin ($size ,$size1$MAX_X-($size+1));

    ncurses_wborder($c,0,00,00,00,0); // border it

    ncurses_wrefresh($c); // show it

return $c;


Happy programming!



This is the curses.h documentation, which will be an excellent reference while
working on any PHP application that uses the ncurses functions.


A great write-up on programming with ncurses in C, much of which translates directly
into PHP.

And as always, use
‘man ncurses’ as each function in C has a man page for it. (i.e. ´man wborder’´).

About the author

Joel De Gan is a seasoned developer currently working for a high-profile domain
name registrar. He is obsessed with PHP and despite working with it on a daily
basis he often continues late into the night to sit up and program.

Joel additionally is the CTO for Tenshimedia LLC ( http://tenshimedia.com

) a multi-faceted media company that among other things runs and maintains JOIhost
( http://www.joihost.com ).

Joel is currently, in his spare time, working on a PHP/ncurses interface for the
Internet file sharing application eDonkey, and a PHP/ncurses packet logger, which
logs from tcpdump in addition to a small side project (http://listbid.com/affil/)
called Listbid.

Many moons ago, at the tender age of 14, Cal touched his first computer. (We're using the term "computer" loosely here, it was a TRS-80 Model 1) Since then his life has never been the same. He graduated from TRS-80s to Commodores and eventually to IBM PC's. For the past 10 years Cal has worked with PHP and MySQL on Linux OSX, and when necessary, Windows. He has built on a variety of projects ranging in size from simple web pages to multi-million dollar web applications. When not banging his head on his monitor, attempting a blood sacrifice to get a particular piece of code working, he enjoys building and managing development teams using his widely imitated but never patented management style of "management by wandering around". Cal is happily married to wife 1.31, the lovely and talented Kathy. Together they have 2 kids who were both bright enough not to pursue a career in IT. Cal blogs at http://blog.calevans.com and is the founder and host of Nomad PHP