使用 PHP 的交互式 shell

发布于 2024-11-03 14:21:46 字数 174 浏览 3 评论 0原文

是否可以单独使用 PHP 创建交互式 shell?

我的意思是像数据库一样, Python 等。如果是, 如何?

Is it possible to create an interactive shell, using PHP alone?

I mean something like you have with databases, Python, etc. If it is, how?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

不弃不离 2024-11-10 14:21:46

是的,这是可能的。为了实现交互,程序必须能够等待并读取来自 标准输入。在 PHP 中,您可以通过打开文件描述符 'php:/ 来读取 stdin /stdin'。摘自不同问题的答案,这是一个PHP 中的交互式用户提示示例(当然,当从命令行运行时):

echo "Continue? (Y/N) - ";

$stdin = fopen('php://stdin', 'r');
$response = fgetc($stdin);
if ($response != 'Y') {
   echo "Aborted.\n";
   exit;
}

当然,要获得整行输入而不是单个字符,您需要 fgets() 而不是 fgetc()。根据您的程序/shell 将执行的操作,整个程序可能会被构造为一个大的连续循环。希望这能让您了解如何开始。如果您想要真正奇特(CLI伪GUI),您可以使用ncurses

Yes, it's possible. In order to be interactive, the program must be able to wait for and read in user input from stdin. In PHP, you can read from stdin by opening a file descriptor to 'php://stdin'. Taken from an answer to different question, here's an example of an interactive user prompt in PHP (when run from the command line, of course):

echo "Continue? (Y/N) - ";

$stdin = fopen('php://stdin', 'r');
$response = fgetc($stdin);
if ($response != 'Y') {
   echo "Aborted.\n";
   exit;
}

Of course, to get a full line of input rather than a single character, you'd need fgets() instead of fgetc(). Depending what your program/shell will do, the whole program might be structured as one big continuous loop. Hopefully that gives you an idea how to get started. If you wanted to get really fancy (CLI pseudo-GUI), you could use ncurses.

甜警司 2024-11-10 14:21:46

由于这个问题已被提出并得到解答,PHP 中添加了一个更好的解决方案。在所有最新的 PHP 版本中,至少是 PHP 5.4,您可以轻松获取用户输入,如下所示:

$input = fgets(STDIN);

Since this question has been asked and answered, a better solution has been added to PHP. In all recent PHP versions, at least PHP 5.4, you can easily get user input as so:

$input = fgets(STDIN);
情话已封尘 2024-11-10 14:21:46

我理解你的问题的方式是你只希望 PHP 解释器在命令行上运行,这样它就会评估你输入的任何 PHP 代码。我一直使用 Python 的这个功能来测试代码片段。在这种情况下,我相信您正在寻找的答案是执行(从命令行):

php -a

假设 PHP 在您的路径中,这将使您进入 PHP 解释器,就像我的一样:

php -a

Interactive shell

php >

从那里您可以开始评估任意 PHP 表达式并查看结果:

php > $a = 'abcdef';
php > echo strlen($a);
6

The way I understand your question you just want the PHP interpreter to run on the command line so you that it will evaluate any PHP code that you type. I use that feature of Python all the time to test code snippets. In which case I believe the answer you are looking for is to execute (from the command line):

php -a

Assuming PHP is in your path this will drop you in to the PHP interpreter, like it does on mine:

php -a

Interactive shell

php >

From there you can start to evaluate arbitrary PHP expressions and see the results:

php > $a = 'abcdef';
php > echo strlen($a);
6
屌丝范 2024-11-10 14:21:46

这是对此的扩展。我添加了一个 isCLI() 检查,以防您在 CLI 和 Web 服务器上运行脚本。否则服务器可能会使用我的函数循环。该解决方案将提示用户,检查输入,并在必要时重新提示用户进行固定输入。

rtrim() 输入,因为如果用户使用 return提交他们的参赛作品,该参赛作品可能会附加到参赛作品中。不需要验证;在这种情况下不要传递函数。

function isCLI() {
    return (php_sapi_name() === 'cli' OR defined('STDIN'));
}

function userPrompt($message, $validator=null) {
    if (!isCLI()) 
        return null;

    print($message);
    $handle = fopen ('php://stdin','r');
    $line = rtrim(fgets($handle), "\r\n");

    if (is_callable($validator) && !call_user_func($validator, $line)) {
        print("Invalid Entry.\r\n");
        return userPrompt($message, $validator);
    } else {
        print("Continuing...\r\n");
        return $line;
    }
}

// Example =====================

function validateSetLangCode($str) {
    return preg_match("/^[A-Z0-9]{3}-[A-Z]{2}$/", $str);
}

$code = userPrompt("Please enter the set / language codes. Use the format 'SET-EN', where SET is the three-letter set code and EN is the two-letter lang code. \r\n", 'validateSetLangCode') ?: 'SET-EN';
var_dump($code);

Here's an expanded take on this. I've added an isCLI() check in case you're run your script both in CLI and on a web server. Otherwise the server could loop using my function. This solution will prompt the user, check the input, and re-prompt the user for fixed input if necessary.

I rtrim() the input, because if the user uses return to submit their entry, that may be appended to the entry. Validation is not necessary; just don't pass a function in that case.

function isCLI() {
    return (php_sapi_name() === 'cli' OR defined('STDIN'));
}

function userPrompt($message, $validator=null) {
    if (!isCLI()) 
        return null;

    print($message);
    $handle = fopen ('php://stdin','r');
    $line = rtrim(fgets($handle), "\r\n");

    if (is_callable($validator) && !call_user_func($validator, $line)) {
        print("Invalid Entry.\r\n");
        return userPrompt($message, $validator);
    } else {
        print("Continuing...\r\n");
        return $line;
    }
}

// Example =====================

function validateSetLangCode($str) {
    return preg_match("/^[A-Z0-9]{3}-[A-Z]{2}$/", $str);
}

$code = userPrompt("Please enter the set / language codes. Use the format 'SET-EN', where SET is the three-letter set code and EN is the two-letter lang code. \r\n", 'validateSetLangCode') ?: 'SET-EN';
var_dump($code);
开始看清了 2024-11-10 14:21:46

由于 PHP 有一个内置的 Unix-only 函数 readline() 来完成此操作,请注意:

我们可以使用并保存 readline 的结果> 在变量中。

#!/usr/bin/php
<?php
    $user = readline("List dir [l] | Say hello [h] | exit [q]: ");

    if ($user === "l"){ system("ls"); }

    if ($user === "h"){ echo "Hello!"; }

    if ($user === "q"){ exit; }

    echo "\nThanks!";

输出示例:

l ls result

h «hello»

q exit

Ctrl + < kbd>C 退出。

Ctrl + D 输入空,继续下一个序列。 “谢谢”。 $user 已定义且为空,没有错误。

Ctrl + D 进行一些输入:无操作。仍在等待输入。

Ctrl + M 继续并获取 $user 中的当前输入。

Ctrl + J 继续并在 $user 中获取当前输入,与 Ctrl + M 的行为相同

Return 继续下一个序列“谢谢”。 $user 可以留空,没有错误。

Ctrl + Z 可用于取消循环并移至顶部循环。如果 var 未在此范围内定义,则 $user 将被取消设置。

根据输入,我们可以使用 !empty 定义空值或进行更多外科测试(readline 响应可以是许多字符)。

如果尚未询问,可以使用 !isset 测试 $user

还有内置的 readline_add_history() 将用户输入存储到对象中,可以通过名称直接检索值(代码清晰):

readline_add_history($user);
print_r(readline_list_history());
print_r(readline_user());

构建真正的复杂性非常有用东西!

了解如何捕获并发送 POSIX 信号

PHP 函数 readline()

Since PHP has a built-in Unix-only function readline() to do exactly that, note:

We can use and hold the result of readline in a variable.

#!/usr/bin/php
<?php
    $user = readline("List dir [l] | Say hello [h] | exit [q]: ");

    if ($user === "l"){ system("ls"); }

    if ($user === "h"){ echo "Hello!"; }

    if ($user === "q"){ exit; }

    echo "\nThanks!";

Example output:

l ls result

h «hello»

q exit

Ctrl + C exit.

Ctrl + D with empty input, continue to the next sequence. «Thanks». $user is defined and empty, no error.

Ctrl + D with some input: No action. Still waiting for input.

Ctrl + M Continue and take the current input in $user.

Ctrl + J Continue and take the current input in $user, same behavior as Ctrl + M.

Return continue to the next sequence «Thanks». $user can stay empty, no error.

Ctrl + Z may be used to cancel a loop and move to the top one. $user will be unset if the var is not defined in this scope.

Depending input, we can define empty values using!empty or do more surgical testings (the readline response can be many chars).

$user can be tested with !isset if not yet asked.

There is also the built-in readline_add_history() to store the user input into an object, where values can be retrieved directly by their name (nice for code clarity):

readline_add_history($user);
print_r(readline_list_history());
print_r(readline_user());

It is very useful to build real complex stuffs!

See how to catch and send POSIX signals.

PHP function readline()

-残月青衣踏尘吟 2024-11-10 14:21:46

如果您希望交互式 shell 处理 PHP 命令,一个例子是 phpsh ,它显然是在 Facebook 创建的,但是它是用Python编写的。

If you want the interactive shell to process PHP commands, one example is phpsh which was apparently created at Facebook, but it is written in Python.

吾性傲以野 2024-11-10 14:21:46

我知道提问者不想要第二个选项,但是对于那些像我一样想要第二个选项的人来说,除了 phpsh 之外,PHP 还有它的 自己的 shell

只需运行 php -a

I know the questioner didn't want the second option, but for those that wanted the second option as I did, in addition to phpsh, PHP also has its own shell:

Just run php -a.

2024-11-10 14:21:46

看看Sheldon

上手非常容易。它包括 Symfony 2Zend Framework 库,它执行大量基本控制台 I/O 工作,并为您提供围绕 命令对象(带有正则表达式路由)和上下文(保存不可变状态)。

我喜欢的一件事是“开箱即用”,您的应用程序可以作为交互式 shell 运行,也可以作为标准脚本运行,您可以从命令行运行、指定命令、传递任何参数,并且当命令完成后应用程序退出。

Check out Sheldon.

It's pretty easy to get started. It includes Symfony 2 and Zend Framework libraries that do a lot of the basic console I/O work and gives you a higher-level abstraction built around command objects (with regex routes) and Contexts (which hold immutable state).

One of the things I love is that "out of the box", your application can run as either an interactive shell, or as a standard script that you can run from the command line, specify a command, pass any arguments, and when the command is finished the application exits.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文