交互式 shell

如果 PHP 使用 --with-readline 选项编译,则 CLI SAPI 使用 -a 选项时会提供交互式 shell。自 PHP 7.1.0 起,如果启用了 readline 扩展 ,交互式 shell 也可以在 Windows 上使用。

使用交互式 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 还有对函数、常量、类名、变量、静态方法调用和类常量的 Tab 键补全功能。

示例 #2 Tab 键补全

当可能有多个补全时,按两次 Tab 键将会得到补全列表:

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

当仅可能有一个补全,按一次 Tab 键即可在同一行中补全剩余:

php > strpt[TAB]ime(

补全也适用于当前交互式 shell 会话期间定义的名称:

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

交互式 shell 会存储你的操作历史记录,可以通过上下键访问。历史记录存储于 ~/.php_history 文件。

CLI SAPI 提供了 cli.pagercli.prompt 两个 php.ini 配置。cli.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 会提供交互模式。 在此模式中,一个完整的 PHP 脚本应该通过 STDIN 给出,并用 CRTL+d (POSIX) 或者 CTRL+z 终止然后 ENTER (Windows),脚本执行。这与不加 -a 选项调用 CLI SAPI 基本相同。

自 PHP 8.1.0 起,如果 readline 扩展不可用,使用 -a 调用 CLI SAPI 会失败。

add a note add a note

User Contributed Notes 14 notes

up
168
Ryan P
10 years ago
Interactive Shell and Interactive Mode are not the same thing, despite the similar names and functionality.

If you type 'php -a' and get a response of 'Interactive Shell' followed by a 'php>' prompt, you have interactive shell available (PHP was compiled with readline support). If instead you get a response of 'Interactive mode enabled', you DO NOT have interactive shell available and this article does not apply to you.

You can also check 'php -m' and see if readline is listed in the output - if not, you don't have interactive shell.

Interactive mode is essentially like running php with stdin as the file input. You just type code, and when you're done (Ctrl-D), php executes whatever you typed as if it were a normal PHP (PHTML) file - hence you start in interactive mode with '<?php' in order to execute code.

Interactive shell evaluates every expression as you complete it (with ; or }), reports errors without terminating execution, and supports standard shell functionality via readline (history, tab completion, etc). It's an enhanced version of interactive mode that is ONLY available if you have the required libraries, and is an actual PHP shell that interprets everything you type as PHP code - using '<?php' will cause a parse error.

Finally, if you're running on Windows, you're probably screwed. From what I'm seeing in other comments here, you don't have readline, and without readline there is no interactive shell.
up
63
spencer at aninternetpresence dot net
11 years ago
In Windows, press Enter after your ending PHP tag and then hit Ctrl-Z to denote the end-of-file:

C:\>php -a
Interactive mode enabled

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

You can use the up and down arrows in interactive mode to recall previous code you ran.
up
18
Anonymous
12 years ago
It seems the interactive shell cannot be made to work in WIN environments at the moment. 

Using "php://stdin", it shouldn't be too difficult to roll your own.  You can partially mimic the shell by calling this simple script (Note: Window's cmd already has an input history calling feature using the up/down keys, and that functionality will still be available during execution here):

<?php

$fp
= fopen("php://stdin", "r");
$in = '';
while(
$in != "quit") {
    echo
"php> ";
   
$in=trim(fgets($fp));
    eval (
$in);
    echo
"\n";
    }
   
?>

Replace 'eval' with code to parse the input string, validate it using is_callable and other variable handling functions, catch fatal errors before they happen, allow line-by-line function defining, etc.  Though Readline is not available in Windows, for more tips and examples for workarounds, see http://www.php.net/manual/en/ref.readline.php
up
11
#linuxmint-es
5 years ago
For use interactive mode enabled on GNU/Linux on distros Debian/Ubuntu/LinuxMint you must install "php*-cli" and "php*-readline" packages from official repository.
Example:
>$sudo aptitude install php5-cli php5-readline

After that you can use interactive mode.
Example:
~ $ php -a
Interactive mode enabled

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

I hope somebody help it!
up
13
Anonymous
12 years ago
Just a few more notes to add...

1) Hitting return does literally mean "execute this command".  Semicolon to note end of line is still required.  Meaning, doing the following will produce a parse error:

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

Whereas doing the following is just fine:

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

2) Fatal errors may eject you from the shell:

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

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

3) User defined functions are not saved in history from shell session to shell session.

4) Should be obvious, but to quit the shell, just type "quit" at the php prompt.

5) In a sense, the shell interaction can be thought of as linearly following a regular php file, except it's live and dynamic.  If you define a function that you've already defined earlier in your current shell, you will receive a fatal "function already defined" error only upon entering that closing bracket.  And, although "including" a toolset of custom functions or a couple of script addon php files is rather handy, should you edit those files and wish to "reinclude" it again, you'll cause a fatal "function x already defined" error.
up
1
elijah at elijahlynn dot net
8 years ago
Bug #55496 Interactive mode doesn't force a newline before the prompt => https://bugs.php.net/bug.php?id=55496

Fixed on July 24th, 2014 @ http://git.php.net/?p=php-src.git;a=commit;h=71d3a69425449972f4efdf7228c6f7e49e090755

Until then, this will work:

php -dcli.prompt="\nphp> " -a
up
1
lee8oi at gmail dot com
10 years ago
I use git-bash in windows to connect to my servers via SSH. When I use the interactive mode via 'php -a' command I have to hit ctrl+d twice to execute the entered code. Example:
(<ctrl+d> denotes hitting ctrl & D)

-bash$ php -a
Interactive mode enabled
<?php
echo 'hello world';
?><br />
<ctrl+d>
<ctrl+d>
hello world<br />
-bash$

Note: this still displays the <br /> tag but without the tag your output would likely be attached to your bash prompt like this:

hello world-bash$
up
0
Gray
2 years ago
When adding colours, don't forget that PHP uses the same 'readline' as Bash does, so it has the same need to wrap all colour codes in special marker characters.

If you simply add raw colour codes to the prompt, you will notice that long lines no longer get wrapped correctly -- Readline no longer knows how wide the prompt is.

To fix this, you need to start each colour code with an '0x01' byte (aka Ctrl-A aka SOH) and end it with the '0x02' byte (aka Ctrl-B aka STX). There are no escapes for these -- you have to literally put the control characters in your php-cli.ini.

For example:

<?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";
?>
up
0
John
4 years ago
If you delete your "~/.php_history", you MUST re-create the file manually!

Because after I deleted my history file, "php -a" (interactive mode) never saved any history anymore.

It only started working after I ran "touch ~/.php_history" to create an empty file. From then on, PHP is saving history again!

I thought this was a bit unusual. Normally, applications recreate their history files themselves. But just be aware of the fact that PHP works this way instead, guys and girls! :-)
up
0
wheat at wheatdesign dot com
5 years ago
If you're stuck on Widows or any other machine where PHP was not compiled with readline support, one solution is to use a web-based PHP CLI. I use this in training classes, especially the sort where people bring their own laptops and I can't assume they have PHP installed. The best one I've found--partly because of the UX and partly because it's free (no credit card required) and quick to setup, is http://repl.it
up
0
alexandrebr at gmail dot com
11 years ago
For those who (just like me) can't get it working, try to press CTRL+D after inserting some commands.

Example:
php
<?php
echo "Hello World!\r\n";
(
Hit CTRL+D here)
Hello World!

This is NOT interactive mode, but may help you.

To have the "-i" available, you'll need the following arguments while compiling PHP:
--with-readline e --with-libedit
up
-4
xEviL
11 years ago
When building php on FreeBSD from ports one can add --with-readline option by manually editing the var CONFIGURE_ARGS in Makefile inside the php port directory and proceeding with build as usual.
up
-2
alexmarcxyz at gmail dot com
4 years ago
While configuring php shell script, We need to take care of these commands, Abstract.php, Compiler.php, Indexer.php, Log.php, You can check more details about these commands at, https://www.cloudways.com/blog/php-shell-scripts-magent . Hope it will help your readers as well as I got help from your and this post.
up
-14
Shane Harter
9 years ago
If you've ever wanted to build your own interactive shell, I released a project recently that makes it insanely easy to build awesome shell apps in PHP. It blends features from Zend2 and Symonfy2 with things like regex routing, state management, etc. Check it out here:

https://github.com/shaneharter/sheldon
To Top