文字

Readline 函数

Table of Contents

  • readline_add_history — 添加一行命令行历史记录
  • readline_callback_handler_install — 初始化一个 readline 回调接口,然后终端输出提示信息并立即返回
  • readline_callback_handler_remove — 移除上一个安装的回调函数句柄并且恢复终端设置
  • readline_callback_read_char — 当一个行被接收时读取一个字符并且通知 readline 调用回调函数
  • readline_clear_history — 清除历史
  • readline_completion_function — 注册一个完成函数
  • readline_info — 获取/设置readline内部的各个变量
  • readline_list_history — 获取命令历史列表
  • readline_on_new_line — 通知readline将光标移动到新行
  • readline_read_history — 读取命令历史
  • readline_redisplay — 重绘显示区
  • readline_write_history — 写入历史记录
  • readline — 读取一行

用户评论:

[#1] david at acz dot org [2007-02-28 09:07:09]

Readline only reads the window size on startup or on SIGWINCH.  This means if the window is resized when not in a readline() call, the next call will have odd behavior due to confusion about the window size.

The work-around is to force Readline to re-read the window size by sending it SIGWINCH.  This is accomplished using the async interface, which installs the signal handler but returns control to PHP.

The following function is a drop-in replacement for readline(), but re-reads the window size every time:

<?php
    
function xreadline($prompt)
    {
        global 
$xreadline$xreadline_line;
        
$code '$GLOBALS["xreadline"] = false;' .
                
'$GLOBALS["xreadline_line"] = $line;' .
                
'readline_callback_handler_remove();';
        
$cb create_function('$line'$code);
        
readline_callback_handler_install($prompt$cb);
        
$signal defined("SIGWINCH") ? SIGWINCH 28;
        
posix_kill(posix_getpid(), $signal);
        
$xreadline true;
        while (
$xreadline)
            
readline_callback_read_char();
        return 
is_null($xreadline_line) ? false $xreadline_line;
    }
?>

[#2] flobee [2006-04-28 10:29:23]

re to: ds at NOSPAM dot undesigned dot org dot za

cool program! note when trying to exec() something:
in the while loop you need to reset exec() returns or you will get all results of all executions (on my my windows and or cygwin :-( 
like:
<?php
// your class prompt()

echo "Enter something or 'exit' to quit\n";
do {
$cmdline = new prompt();
$buffer = $cmdline->get('shell command: ');
// init/ reset first!
$data = null;
$return = null;
// now start:
echo "You said: $buffer\n";
if (!empty($buffer)) {
$x = exec($buffer, $data, $return);
print_r($data);
}
} while ($buffer !== "exit");
echo "Goodbye\n";

[#3] jeffrey at thompsonic dot com [2005-02-22 06:18:41]

Here's an easy way without readline() if you don't have it compiled in already:

   $fp = fopen("php://stdin","r");
   $line = rtrim(fgets($fp, 1024);

[#4] jcl atNOSPAM jcl dot name [2004-11-23 09:40:45]

Even better than 'plz at dont dot spam' in only one line :) :

@c:\\php\\cli\\php.exe script.php %*

Cheers,
Jean-Charles

[#5] plz at dont dot spam [2004-08-08 01:50:54]

To get all arguments passed to a batch file in one variable
rather than using %1 %2 %3 etc;

:LOOP
if "%1" == "" goto DONE
set args=%args% %1
shift
goto LOOP
:DONE
@c:\\php\\cli\\php.exe script.php %args%
set args=

[#6] ds at NOSPAM dot undesigned dot org dot za [2003-12-04 20:04:46]

You can open /dev/tty on unix systems or \con in windows, with ob_implicit_flush(true) to write output unbuffered.  Works like a charm :-)

-------------------------------

#!/usr/local/bin/php -q
<?php

set_time_limit
(0);
@
ob_end_flush();
ob_implicit_flush(true);

class 
prompt {
  var 
$tty;

  function 
prompt() {
    if (
substr(PHP_OS03) == "WIN") {
      
$this->tty fOpen("\con""rb");
    } else {
      if (!(
$this->tty fOpen("/dev/tty""r"))) {
        
$this->tty fOpen("php://stdin""r");
      }
    }
  }

  function 
get($string$length 1024) {
    echo 
$string;
    
$result trim(fGets($this->tty$length));
    echo 
"\n";
    return 
$result;
  }
}

echo 
"Enter something or 'exit' to quit\n";
do {
  
$cmdline = new prompt();
  
$buffer $cmdline->get("Something: ");
  echo 
"You said: $buffer\n";
} while (
$buffer !== "exit");
echo 
"Goodbye\n";

?>

[#7] jewfish at jewfish dot net [2002-06-10 16:05:22]

There is a simpler way to do a multiline read than above:

function multiline() {
    while(($in = readline("")) != ".")
        $story .= ($PHP_OS == "WINNT") ? "\r\n".$in :
                                         "\n".$in;

    return $story;
}

[#8] joshua at neocodesoftware.com [2002-04-21 03:17:43]

Here's an example simple readline-like way to input from command line on windows - the single line is from http://www.phpbuilder.com/columns/darrell20000319.php3, the multiline is something I added...

<?php
function read () {
    
# 4092 max on win32 fopen

    
$fp=fopen("php://stdin""r");
    
$in=fgets($fp,4094);
    
fclose($fp);

    
# strip newline
    
(PHP_OS == "WINNT") ? ($read str_replace("\r\n"""$in)) : ($read str_replace("\n"""$in));

    return 
$read;
}

function 
multilineread () {
    do {
        
$in read();

        
# test exit
        
if ($in == ".") return $read;

        
# concat input
        
(PHP_OS == "WINNT") ? ($read $read . ($read "\r\n" "") . $in) : ($read $read "\n" $in);

    } while (
$inp != ".");

    return 
$read;
}

print(
"End input with . on line by itself.\n");

print(
"What is your first name?\n");
$first_name multilineread();

print(
"What is your last name?\n");
$last_name read();

print(
"\nHello, $first_name $last_name! Nice to meet you! \n");
?>

[#9] [2002-04-14 07:17:08]

[Ed. note: you can use fopen("php://stdin", "w") to achieve the same thing, works on both Windows and Unix)]

I wanted to get console input in a PHP script running on windows, so I made a little hack, which is so simple, it is clearly public domain.  What I did was write a C++ program to get a line, then output it.  Then all that is needed is to exec() that program and capture the output - readline() for windows.  The C++ source is as follows:

#include <iostream.h>
#include <string>
void main()
{
    string input;
    cin >> input;
    cout << input;
}

It works wonderfully for my purposes, since I love the PHP language and want to have console input.

Justin Henck

上一篇: 下一篇: