PHP Conference Japan 2024

Readline 函式

目錄

新增註解

使用者貢獻的註解 10 則註解

4
david at acz dot org
17 年前
Readline 只會在啟動時或收到 SIGWINCH 訊號時讀取視窗大小。這表示如果在非 readline() 呼叫期間調整視窗大小,則下次呼叫會因為視窗大小的混淆而產生異常行為。

解決方法是透過發送 SIGWINCH 訊號強制 Readline 重新讀取視窗大小。這是透過非同步介面完成的,該介面會安裝訊號處理程式,但將控制權返回 PHP。

以下函式是 readline() 的替代方案,但每次都會重新讀取視窗大小

<?
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;
}
?>
1
flobee
18 年前
回覆:ds at NOSPAM dot undesigned dot org dot za

程式碼很棒!注意,當嘗試在 while 迴圈中執行 exec() 時
您需要重設 exec() 的返回值,否則您將會得到所有執行的所有結果(在我的 Windows 和/或 Cygwin 上 :-(
例如
<?php
// 你的類別 prompt()

echo "輸入一些內容或輸入 'exit' 退出\n";
do {
$cmdline = new prompt();
$buffer = $cmdline->get('shell 命令: ');
// 先初始化/重置!
$data = null;
$return = null;
// 現在開始:
echo "你輸入了: $buffer\n";
if (!empty(
$buffer)) {
$x = exec($buffer, $data, $return);
print_r($data);
}
} while (
$buffer !== "exit");
echo
"再見\n";
1
jcastromail at yahoo dot es
2 年前
Windows。
到目前為止,Windows 上的 64 位元 PHP 8.1 不支援所有函式

支援的
readline_add_history
readline_clear_history
readline_completion_function
readline_info
readline_list_history
readline_read_history
readline_write_history
readline

不支援:(甚至未定義該函式)

readline_callback_handler_install
readline_callback_handler_remove
readline_callback_read_char
readline_on_new_line
readline_redisplay

如果您想在 Windows 中讀取一個鍵(非阻塞式),您可以使用以下程式碼

$out='';
$ret='';
$keys='1234567890abcdefghijklmnopqrstuvwxyz'."á";
$default="á";
while(true) {
exec("choice /N /C $keys /D $default /T 1",$out,$ret);
if($out[0]!=="á") {
var_dump($out[0]);
}
$out=[];
}

這並不優雅,而且它每 1 秒呼叫一次 choice,但它可以完成工作(至少對於某些鍵來說)。
0
jewfish at jewfish dot net
22 年前
有一種比上面更簡單的方法可以進行多行讀取

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

return $story;
}
0
匿名
22 年前
[編者註:您可以使用 fopen("php://stdin", "w") 來達到同樣的效果,在 Windows 和 Unix 上都可以運作]

我想在 Windows 上執行的 PHP 腳本中取得控制台輸入,所以我做了一個小技巧,它非常簡單,顯然是公開的。我所做的是編寫一個 C++ 程式來取得一行,然後輸出它。然後只需要 exec() 該程式並擷取輸出 - readline() for windows。C++ 原始碼如下

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

它非常適合我的目的,因為我喜歡 PHP 語言,並且想要有控制台輸入。

Justin Henck
-1
jeffrey at thompsonic dot com
19 年前
如果您尚未編譯 readline(),這裡有一個簡單的方法可以不用它。

$fp = fopen("php://stdin","r");
$line = rtrim(fgets($fp, 1024));
-1
ds at NOSPAM dot undesigned dot org dot za
21 年前
您可以在 Unix 系統上開啟 /dev/tty 或在 Windows 中開啟 \con,並使用 ob_implicit_flush(true) 來無緩衝地寫入輸出。效果非常好 :-)

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

#!/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
"輸入一些內容或輸入 'exit' 退出\n";
do {
$cmdline = new prompt();
$buffer = $cmdline->get("輸入內容: ");
echo
"您輸入了: $buffer\n";
} while (
$buffer !== "exit");
echo
"再見\n";

?>
-1
jcl atNOSPAM jcl dot name
20 年前
比 'plz at dont dot spam' 更好,而且只有一行 :)

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

致敬,
Jean-Charles
-1
joshua at neocodesoftware.com
22 年前
以下是在 Windows 命令列中輸入類似 readline 方式的簡單範例 - 單行來自 http://www.phpbuilder.com/columns/darrell20000319.php3, 多行是我添加的...

<?
function read () {
# Win32 fopen 最大值 4092

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

# 移除換行符號
(PHP_OS == "WINNT") ? ($read = str_replace("\r\n", "", $in)) : ($read = str_replace("\n", "", $in));

return $read;
}

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

# 測試結束條件
if ($in == ".") return $read;

# 串接輸入
(PHP_OS == "WINNT") ? ($read = $read . ($read ? "\r\n" : "") . $in) : ($read = $read . "\n" . $in);

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



return $read;
}

print("請以單獨一行的「.」結束輸入。\n");

print("請問您的名字是?\n");
$first_name = multilineread();

print("請問您的姓氏是?\n");
$last_name = read();

print("\n您好,$first_name $last_name!很高興認識您!\n");
?>
-2
plz at dont dot spam
20 年前
將批次檔傳遞的所有參數放入一個變數中,
而不是使用 %1 %2 %3 等等;

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