采用php开发终端字符界面
2009年6月1日
众所周知,PHP通常情况下都用于动态网站的开发,抑或采用PHP_CLI进行命令行的开发。其实PHP除了能进行以上两种开发外,还可以进行终端系统的开发。
废话以后再讲,先上个图一看便知。

这个界面没见过?不会吧,各位XD去过银行吧?留心看过其操作界面没有?想起来了?对了,他们的操作界面就是类似于这个东东。当然这只是一个登录界面而已。虽然这只是一个登录界面,但其所有代码均采用PHP完成,没想到吧?
那就来看看Code:
<?php
define('MY_NCURSES_KEY_ESC', 27);
define('MY_NCURSES_KEY_NUM_MIN', 48);//0
define('MY_NCURSES_KEY_NUM_MAX', 57);//9
define('MY_NCURSES_KEY_INPUT_MIN', 65);//A
define('MY_NCURSES_KEY_INPUT_MAX', 122);//z
function login_win() {
$login_rows = 10;
$login_cols = 40;
$login_y = ((25 - $login_rows) >> 1) + 1;
$login_x = ((80 - $login_cols) >> 1) + 1;
ncurses_init();
$login_win = ncurses_newwin ( $login_rows, $login_cols, $login_y, $login_x );
if (empty ( $login_win )) {
trigger_error ( 'unable to create window' );
return NULL;
}
ncurses_wborder ( $login_win, 0, 0, 0, 0, 0, 0, 0, 0 );
ncurses_wrefresh ( $login_win );
ncurses_wattron ( $login_win, NCURSES_A_REVERSE );
ncurses_mvwaddstr ( $login_win, 0, 2, "登录" );
ncurses_wattroff ( $login_win, NCURSES_A_REVERSE );
$well_str = "请输入用户名和密码";
$title_x = ( int ) ($login_cols - strlen ( $well_str ) >> 1) + 1;
$title_y = 2;
ncurses_mvwaddstr ( $login_win, $title_y, $title_x, $well_str );
$name_var ="";
$name_len = 0;
$pass_var = "";
$pass_len = 0;
$u_cursor_y = 4;
$u_cursor_x = 12;
$p_cursor_y = 5;
$p_cursor_x = 12;
$b_y = 7;
$b_commit_x = 8;
$b_reset_x = 20;
$v_current = 0;
$h_current = 0;
$do_loop = 1;
$commit_str = "登录";
$reset_str = "重置";
ncurses_mvwaddstr ( $login_win, $b_y, $b_commit_x, $commit_str );
ncurses_mvwaddstr ( $login_win, $b_y, $b_reset_x, $reset_str );
//第四行第四列
ncurses_mvwaddstr($login_win, 4, 4, "用户名:");
//第五行第四列
ncurses_mvwaddstr($login_win, 5, 4, "密 码:");
ncurses_wmove ( $login_win, $u_cursor_y, $u_cursor_x );
ncurses_wrefresh ( $login_win );
ncurses_keypad ( $login_win, TRUE );
ncurses_noecho ();
ncurses_curs_set ( 1 );
$logined = FALSE;
while ($do_loop) {
$key = ncurses_wgetch($login_win);
$v_move = 0;
$h_move = 0;
switch ($key) {
case NCURSES_KEY_UP:
if ($v_current > 0) {
$v_move = -1;
}
break;
case NCURSES_KEY_DOWN:
if ($v_current < 2) {
$v_move = 1;
}
break;
case NCURSES_KEY_LEFT:
if ($h_current > 0) {
$h_move = -1;
}
break;
case NCURSES_KEY_RIGHT:
if ($h_current < 1) {
$h_move = 1;
}
break;
case MY_NCURSES_KEY_LF:
case MY_NCURSES_KEY_CR:
//reset
if (($h_current == 1) &&($v_current == 2)) {
$name_var = "";
$name_len = 0;
$name_char= "";
$pass_var = "";
$pass_len = 0;
$pass_char= "";
$u_cursor_x = 12;
$p_cursor_x = 12;
$fill = str_pad(" ", 10);
ncurses_mvwaddstr ( $login_win, $u_cursor_y, $u_cursor_x, $fill );
ncurses_mvwaddstr ( $login_win, $p_cursor_y, $p_cursor_x, $fill );
ncurses_mvwaddstr ( $login_win, $u_cursor_y, $u_cursor_x, "" );
ncurses_mvwaddstr ( $login_win, $p_cursor_y, $p_cursor_x, "" );
}elseif (($h_current == 0) && ($v_current == 2)) {
//login
if (($name_var == "cc") && ($pass_var == "cc")) {
;
$do_loop = 0;
$logined = TRUE;
}
}
break;
case MY_NCURSES_KEY_BACKSPACE:
if (($v_current == 0) && ($name_len > 0)) {
$name_len --;
$name_var = substr ( $name_var, 0, $name_len );
$u_cursor_x --;
ncurses_mvwaddstr ( $login_win, $u_cursor_y, $u_cursor_x, "" );
} else if (($v_current == 1) && ($pass_len > 0)) {
$pass_len --;
$pass_var = substr ( $pass_var, 0, $pass_len );
$p_cursor_x --;
ncurses_mvwaddstr ( $login_win, $p_cursor_y, $p_cursor_x, "" );
}
break;
case MY_NCURSES_KEY_ESC:
ncurses_flushinp ();
$do_loop = 0;
$logined = FALSE;
break;
default:
if ((($key >= MY_NCURSES_KEY_INPUT_MIN) && ($key <= MY_NCURSES_KEY_INPUT_MAX)) ||
(($key >= MY_NCURSES_KEY_NUM_MIN) && ($key <= MY_NCURSES_KEY_NUM_MAX))) {
if (($v_current == 0) && ($name_len < 10)) {
$name_len ++;
$name_var .= $name_char = chr ( $key );
ncurses_mvwaddstr ( $login_win, $u_cursor_y, $u_cursor_x, $name_char );
$u_cursor_x ++;
} else if (($v_current == 1) && ($pass_len < 10)) {
$pass_len ++;
$pass_var .= $pass_char = chr ( $key );
ncurses_mvwaddstr ( $login_win, $p_cursor_y, $p_cursor_x, "*" );
$p_cursor_x ++;
}
}
break;
}
$v_current += $v_move;
if ($v_current == 0) {
ncurses_wattron ( $login_win, NCURSES_A_REVERSE );
ncurses_mvwaddstr ( $login_win, $u_cursor_y, $u_cursor_x, "" );
ncurses_wattroff ( $login_win, NCURSES_A_REVERSE );
}elseif ($v_current == 1) {
ncurses_wattron ( $login_win, NCURSES_A_REVERSE );
ncurses_mvwaddstr ( $login_win, $p_cursor_y, $p_cursor_x, "" );
ncurses_wattroff ( $login_win, NCURSES_A_REVERSE );
}else {
$h_current += $h_move;
if ($h_current == 0) {
ncurses_mvwaddstr ( $login_win, $b_y, $b_reset_x, $reset_str );
ncurses_wattron ( $login_win, NCURSES_A_REVERSE );
ncurses_mvwaddstr ( $login_win, $b_y, $b_commit_x, $commit_str );
ncurses_wattroff ( $login_win, NCURSES_A_REVERSE );
}else {
ncurses_mvwaddstr ( $login_win, $b_y, $b_commit_x, $commit_str );
ncurses_wattron ( $login_win, NCURSES_A_REVERSE );
ncurses_mvwaddstr ( $login_win, $b_y, $b_reset_x, $reset_str );
ncurses_wattroff ( $login_win, NCURSES_A_REVERSE );
}
}
ncurses_wrefresh ( $login_win );
}// end while
ncurses_werase($login_win);
ncurses_clear();
ncurses_end();
if (isset($logined) && $logined) {
return TRUE;
}else {
return FALSE;
}
}
?>
现在明白是怎么回事了吧?当然各位兄弟把这代码拿下去,可能你们的环境中是无法RUN的,因为这采用了其它的PHP包。
对于采用的什么包,各位XDJM,还敬请关注本博,稍后将奉上相关的PHP包的安装与配置 :)
我只知道PHP还可以进行SHELL方面的开发,不知道跟这有没有什么关系?
这个严格意义上也算是PHP CLI的一种应用吧
但这种应用较为特殊,它是基本终端的开发,能够操作终端的打印机等设备。
不好错 也不运行 my god的
不报错 也不运行
明白了 作者就是运用ncurses完成的 这个代码并不完全对 缺少头#!。。。。 还缺少初始化 之后再点用function就可以了 不过我的linux不支持中文 改成英文的就ok了 还有一个楼主代码没有定义颜色 贴的图根本就不是上面的代码 哈哈哈哈哈哈 都被我发现了 我这脑袋咋长的呀 哈哈哈哈
楼主你说说switch的流程吧 怎么设计的 我看的有点乱 登陆还有重置都没有实现吧 这只是一个简单的页面而已 ???
@ourmeng
这个啊? 上面的代码就是效果图的代码。
我这是采用NetTerm模拟的终端,颜色呢,是NetTerm所默认的。因为直接采用真正的终端我也无法将该图抓下来。
这个switch流程其实很简单啊, 就是根据所捕获的用户输入进行相应的处理而已啊。。。
这个需要看懂每一个分支的功能,你就会明白的。
@achao 我看懂了 谢了
@ourmeng
其实也很简单的,只是需要静下心来看而已