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;
}
?>
CXXXV. GNU Readline
Úvod
readline() funkce implementují rozhraní ke GNU Readline knihovně. Tyto funkce poskytují editovatelné příkazové řádky. Příkladem může být způsob, jakým vám Bash umožňuje vkládat znaky nebo listovat historií příkazů pomocí kláves pro pohyb kurzoru. Z interaktivní povahy této knihovny vyplývá, že není příliš užitečná pro psaní webových aplikací, ale může být užitečná při psaní skriptů, které se mají spouštět z příkazové řádky.
Poznámka: Toto rozšíření není k dispozici na platformách Windows.
Požadavky
Abyste mohli používat readline funkce, musíte nainstalovat libreadline. Domovskou stránkou GNU Readline projektu je » http://cnswww.cns.cwru.edu/~chet/readline/rltop.html. Udržuje jej Chet Ramey, který je také autorem Bashe.
Tyto funkce můžete používat také s knihovnou libedit, ne-GPL náhradou za knihovnu readline. Knihovna libedit je pod licencí BSD a stáhnout lze z » http://www.thrysoee.dk/editline/.
Instalace
Abyste mohli používat tyto funkce, musíte zkompilovat CGI nebo CLI verzi PHP s podporou pro readline. PHP musíte zkonfigurovat s volbou --with-readline[=DIR]. Pokud chcete používat libedit jako náhradu za readline, zkonfigurujte PHP s volbou --with-libedit[=DIR].
Konfigurace běhu
Toto rozšíření nemá definováno žádné konfigurační direktivy.
Typy prostředků
Toto rozšíření nemá definován žádný typ prostředku (resource).
Předdefinované konstanty
Toto rozšíření nemá definovány žádné konstanty.
Obsah
- readline_add_history — Přidat řádek do historie
- readline_callback_handler_install — Initializes the readline callback interface and terminal, prints the prompt and returns immediately
- readline_callback_handler_remove — Removes a previously installed callback handler and restores terminal settings
- readline_callback_read_char — Reads a character and informs the readline callback interface when a line is received
- readline_clear_history — Smazat historii
- readline_completion_function — Zaregistrovat dokončující funkci
- readline_info — Zjistit/nastavit různé interní proměnné readline
- readline_list_history — Vypsat historii
- readline_on_new_line — Inform readline that the cursor has moved to a new line
- readline_read_history — Vrátit historii
- readline_redisplay — Redraws the display
- readline_write_history — Zapsat historii
- readline — Přečíst řádek
GNU Readline
28-Feb-2007 06:07
28-Apr-2006 07: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 03: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);
23-Nov-2004 06: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 10: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 05: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 01: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 12: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
