交互式 shell

如果 PHP 使用 --with-readline 选项编译,则 CLI SAPI 使用 -a 选项提供交互式 shell。从 PHP 7.1.0 开始,如果启用了 readline 扩展,Windows 上也提供交互式 shell。

使用交互式 shell,您可以输入 PHP 代码并直接执行。

示例 #1 使用交互式 shell 执行代码

$ php -a
Interactive shell

php > echo 5+8;
13
php > function addTwo($n)
php > {
php { return $n + 2;
php { }
php > var_dump(addtwo(2));
int(4)
php >

交互式 shell 还为函数、常量、类名、变量、静态方法调用和类常量提供制表符完成。

示例 #2 制表符完成

当有多个可能的完成时,按两次制表键将显示这些完成的列表。

php > strp[TAB][TAB]
strpbrk   strpos    strptime  
php > strp

当只有一个可能的完成时,按一次制表键将在同一行上完成其余部分。

php > strpt[TAB]ime(

完成也适用于在当前交互式 shell 会话期间定义的名称。

php > $fooThisIsAReallyLongVariableName = 42;
php > $foo[TAB]ThisIsAReallyLongVariableName

交互式 shell 存储您的历史记录,可以使用向上和向下键访问。历史记录保存在 ~/.php_history 文件中。

CLI SAPI 提供 php.ini 设置 cli.pagercli.promptcli.pager 设置允许外部程序(例如 less)充当输出的分页器,而不是直接显示在屏幕上。 cli.prompt 设置使更改 php > 提示符成为可能。

还可以使用简写符号在交互式 shell 中设置 php.ini 设置。

示例 #3 在交互式 shell 中设置 php.ini 设置

cli.prompt 设置

php > #cli.prompt=hello world :> 
hello world :>

使用反引号,可以在提示符中执行 PHP 代码。

php > #cli.prompt=`echo date('H:i:s');` php > 
15:49:35 php > echo 'hi';
hi
15:49:43 php > sleep(2);
15:49:45 php >

将分页器设置为 less

php > #cli.pager=less
php > phpinfo();
(output displayed in less)
php >

cli.prompt 设置支持一些转义序列。

cli.prompt 转义序列
序列 描述
\e 用于向提示符添加颜色。例如 \e[032m\v \e[031m\b \e[34m\> \e[0m
\v PHP 版本。
\b 指示 PHP 所在的块。例如 /* 表示在多行注释中。外层范围由 php 表示。
\> 指示提示符字符。默认情况下,这是 >,但在 shell 在未终止的块或字符串中时会发生变化。可能的字符是: ' " { ( >

注意:

通过 auto_prepend_fileauto_append_file 包含的文件在此模式下解析,但有一些限制 - 例如,函数必须在调用之前定义。

交互模式

如果 readline 扩展不可用,则在 PHP 8.1.0 之前,使用 -a 选项调用 CLI SAPI 将提供交互模式。在此模式下,应通过 STDIN 提供完整的 PHP 脚本,并在使用 CRTL+d (POSIX) 或 CTRL+z 后跟 ENTER (Windows) 终止后,将评估此脚本。这基本上与在没有 -a 选项的情况下调用 CLI SAPI 相同。

从 PHP 8.1.0 开始,如果 readline 扩展不可用,则使用 -a 选项调用 CLI SAPI 将失败。

添加笔记

用户贡献的笔记 7 条笔记

Ryan P
12 年前
交互式 Shell 和交互模式不是一回事,尽管它们有相似的名称和功能。

如果您输入 'php -a' 并得到 'Interactive Shell' 后跟 'php>' 提示符的响应,则您有交互式 shell 可用(PHP 使用 readline 支持编译)。如果相反,您得到 'Interactive mode enabled' 的响应,则您没有交互式 shell 可用,本文不适用于您。

您还可以检查 'php -m' 并查看 readline 是否列在输出中 - 如果没有,则您没有交互式 shell。

交互模式本质上就像使用 stdin 作为文件输入运行 php。您只需输入代码,当您完成时(Ctrl-D),php 将执行您输入的任何内容,就像它是正常的 PHP (PHTML) 文件一样 - 因此您以 '<?php' 开始交互模式才能执行代码。

交互式 shell 在您完成输入时(带有 ; 或 })评估每个表达式,在不终止执行的情况下报告错误,并通过 readline 支持标准 shell 功能(历史记录、制表符完成等)。它是交互模式的增强版本,只有在您拥有必需的库时才可用,并且是一个实际的 PHP shell,它将您输入的任何内容解释为 PHP 代码 - 使用 '<?php' 会导致解析错误。

最后,如果您在 Windows 上运行,您可能就完了。从我在其他评论中看到的情况来看,您没有 readline,如果没有 readline,就没有交互式 shell。
spencer at aninternetpresence dot net
12 年前
在 Windows 中,在您的结束 PHP 标签后按 Enter,然后按 Ctrl-Z 表示文件结束。

C:\>php -a
Interactive mode enabled

<?php
echo "Hello, world!";
?>
^Z
Hello, world!

您可以在交互模式中使用向上和向下箭头来回忆之前运行的代码。
#linuxmint-es
6 年前
要在 GNU/Linux 上的 Debian/Ubuntu/LinuxMint 发行版上使用启用交互模式,您必须从官方存储库安装 "php*-cli" 和 "php*-readline" 包。
示例
>$sudo aptitude install php5-cli php5-readline

之后您就可以使用交互模式。
示例
~ $ php -a
Interactive mode enabled

php >echo "hola mundo!\n";
hola mundo!
php >

希望有人能帮到您!
匿名
14 年前
再补充几点...

1) 按回车键实际上意味着“执行此命令”。仍然需要分号来表示行尾。这意味着,执行以下操作将产生解析错误

php > print "test"
php > print "asdf";

而执行以下操作就可以了

php > print "test"
php > ."asdf";

2) 严重错误可能会将您从 shell 中弹出

name@local:~$ php -a
php > asdf();

Fatal Error: call to undefined function...
name@local:~$

3) 用户定义的函数不会从一个 shell 会话保存到另一个 shell 会话的历史记录中。

4) 应该很明显,但要退出 shell,只需在 php 提示符下键入 "quit"。

5) 从某种意义上说,shell 交互可以被认为是线性地遵循一个常规的 php 文件,除了它是实时且动态的。如果您定义了一个您之前在当前 shell 中定义过的函数,您只会在线程输入结束大括号时收到“函数已定义”的严重错误。并且,虽然“包含”自定义函数的工具集或几个脚本附加 php 文件非常方便,但如果您编辑这些文件并希望再次“重新包含”它们,您将导致“函数 x 已定义”的严重错误。
Gray
4 年前
添加颜色时,不要忘记 PHP 使用与 Bash 相同的 'readline',因此它需要将所有颜色代码包装在特殊标记字符中。

如果您只是将原始颜色代码添加到提示符中,您会注意到长行不再正确换行 - Readline 不再知道提示符的宽度。

要解决此问题,您需要在每个颜色代码的开头添加一个 '0x01' 字节(也称为 Ctrl-A 也称为 SOH)并在结尾添加 '0x02' 字节(也称为 Ctrl-B 也称为 STX)。这些没有转义符 - 您必须将控制字符字面量放在 php-cli.ini 中。

例如

<?php

// cli.prompt = <SOH>\e[1m<STX> PHP! \> <SOH>\e[m<STX>

echo "cli.prompt = \x01\\e[1m\x02 PHP! \x01\\e[m\x02\n";
?>
turabgarip at gmail dot com
4 个月前
请注意,析构函数不会在通过任何方法退出交互式 shell 时触发。(例如 CTRL + D、CTRL + Z 或 CTRL + C)。

由于交互式 shell 本质上是一个持续运行的环境,析构函数的“脚本结束”条件永远不会满足。退出交互式 shell 并不被视为脚本结束,而是解释器进程的结束。由于进程已经终止,它无法运行析构函数。

因此,运行析构函数的唯一方法是移除对相应对象的引用。例如:

<?php

class A {
public function
__destructor() {
// 退出 PHP 交互式 shell 会话后,此代码不会运行。
}
}

$a = new A();

// 这是运行析构函数的唯一方法。
$a = null; // 或者;
unset($a);

?>
John
6 年前
如果你删除了 "~/.php_history" 文件,你必须手动重新创建它!

因为在我删除了历史文件后,"php -a"(交互模式)不再保存任何历史记录了。

直到我运行 "touch ~/.php_history" 创建一个空文件后,PHP 才恢复了保存历史记录的功能!

我认为这有点不寻常。通常情况下,应用程序会自己重新创建它们的历史文件。但请注意,PHP 采用的是这种方式,各位!:-)
To Top