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:
<?
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;
}
?>
GNU Readline
導入
readline 関数群は、GNU Readline ライブラリへの インターフェースを実装したものです。これらの関数は、コマンドラインの 編集機能を提供します。一例をあげると、Bash において文字を挿入したり コマンド履歴を走査したりする際に、矢印キーを使用することを 可能にしているものです。 このライブラリは対話的なものであるため、Web アプリケーションで 使用されることはほとんどないでしょう。しかし、 コマンドライン から PHP を使用するスクリプトを書く際には有用です。
注意: この拡張モジュールは Windows 環境では利用できません。
要件
readline 関数を使用するには、libreadline をインストールすることが 必要です。libreadline は、» http://cnswww.cns.cwru.edu/~chet/readline/rltop.html にある GNU Readline プロジェクトのホームページから入手可能です。このライブラリは、Bash の 作者でもある Chet Ramey により管理されています。
この関数を libeditライブラリで使用することも可能です。これは readline ライブラリの代替品で、非 GPL です。 libeditライブラリは BSD ライセンスで配布され、 » http://www.thrysoee.dk/editline/ から入手可能です。
インストール手順
この関数を使用するには、readline サポートを有効にして CGI 版または CLI 版の PHP をコンパイルする必要があります。PHP の configure に --with-readline[=DIR] を指定する必要が あります。readline の代替品である libedit を使用したい場合、PHP の configure に --with-libedit[=DIR] を指定してください。
実行時設定
設定ディレクティブは定義されていません。
リソース型
リソース型は定義されていません。
定義済み定数
定数は定義されていません。
目次
- readline_add_history — ヒストリに 1 行追加する
- 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 — 一行読み込む
Readline
01-Mar-2007 02:07
05-Nov-2006 07:04
Some Tricks with the PHP readline Modus
http://www.michael-berndt.de/ie/tux/readline.htm
29-Apr-2006 02:29
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";
22-Feb-2005 11:18
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);
24-Nov-2004 02:40
Even better than 'plz at dont dot spam' in only one line :) :
@c:\\php\\cli\\php.exe script.php %*
Cheers,
Jean-Charles
08-Aug-2004 05:50
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=
05-Dec-2003 01:04
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_OS, 0, 3) == "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";
?>
11-Jun-2002 08:05
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;
}
21-Apr-2002 07:17
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...
<?
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");
?>
[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