Π˜Π½Ρ‚Π΅Ρ€Π°ΠΊΡ‚ΠΈΠ²Π½Π°Ρ консоль

ΠœΠΎΠ΄ΡƒΠ»ΡŒ CLI SAPI ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ ΠΈΠ½Ρ‚Π΅Ρ€Π°ΠΊΡ‚ΠΈΠ²Π½ΡƒΡŽ консоль, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ запускаСт опция -a, Ссли PHP скомпилировали с ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠΌ --with-readline. Начиная с PHP PHP 7.1.0 интСрактивная консоль Ρ‚Π°ΠΊΠΆΠ΅ доступна Π² ОБ Windows, Ссли ΠΌΠΎΠ΄ΡƒΠ»ΡŒ readline Π²ΠΊΠ»ΡŽΡ‡ΠΈΠ»ΠΈ.

Π˜Π½Ρ‚Π΅Ρ€Π°ΠΊΡ‚ΠΈΠ²Π½Π°Ρ консоль ΡƒΠΌΠ΅Π΅Ρ‚ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ сам PHP-ΠΊΠΎΠ΄.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ #1 Запуск ΠΊΠΎΠ΄Π° Π² ΠΈΠ½Ρ‚Π΅Ρ€Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎΠΉ консоли

$ 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 >

Π˜Π½Ρ‚Π΅Ρ€Π°ΠΊΡ‚ΠΈΠ²Π½Π°Ρ консоль ΠΏΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ клавиши Tab Ρ‚Π°ΠΊΠΆΠ΅ автодополняСт названия Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, констант, классов, ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…, Π²Ρ‹Π·ΠΎΠ²Ρ‹ статичСских ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² ΠΈ константы классов.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ #2 АвтодополнСниС ΠΏΠΎ клавишС Tab

Π”Π²ΠΎΠΉΠ½ΠΎΠ΅ Π½Π°ΠΆΠ°Ρ‚ΠΈΠ΅ клавиши Tab ΠΏΠΎΠΊΠ°ΠΆΠ΅Ρ‚ список Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠ², Ссли доступно большС ΠΎΠ΄Π½ΠΎΠ³ΠΎ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π° дополнСния:

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

Когда Π΅ΡΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄Π½ΠΎ Π΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅, ΠΎΠ΄ΠΈΠ½ΠΎΡ‡Π½ΠΎΠ΅ Π½Π°ΠΆΠ°Ρ‚ΠΈΠ΅ Tab Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚ ΠΎΡΡ‚Π°Π²ΡˆΠΈΠΉΡΡ тСкст Π½Π° Ρ‚ΠΎΠΉ ΠΆΠ΅ самой строкС:

php > strpt[TAB]ime(

Π”ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Ρ‚Π°ΠΊΠΆΠ΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ для ΠΈΠΌΡ‘Π½, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ объявили Π² Ρ‚Π΅Ρ‡Π΅Π½ΠΈΠ΅ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ ΠΈΠ½Ρ‚Π΅Ρ€Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎΠΉ сСссии:

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

Π˜Π½Ρ‚Π΅Ρ€Π°ΠΊΡ‚ΠΈΠ²Π½Π°Ρ ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠ° Ρ…Ρ€Π°Π½ΠΈΡ‚ ΠΈΡΡ‚ΠΎΡ€ΠΈΡŽ ΠΊΠΎΠΌΠ°Π½Π΄, для доступа ΠΊ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π½Π°ΠΆΠΈΠΌΠ°ΡŽΡ‚ стрСлки Π²Π²Π΅Ρ€Ρ… ΠΈ Π²Π½ΠΈΠ·. Π˜ΡΡ‚ΠΎΡ€ΠΈΡ хранится Π² Ρ„Π°ΠΉΠ»Π΅ ~/.php_history. Начиная с PHP 8.4.0 ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΠΏΡƒΡ‚ΡŒ ΠΊ Ρ„Π°ΠΉΠ»Ρƒ с историСй ΠΊΠΎΠΌΠ°Π½Π΄ ΠΌΠΎΠΆΠ½ΠΎ Π² ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ окруТСния PHP_HISTFILE.

ΠœΠΎΠ΄ΡƒΠ»ΡŒ CLI SAPI ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ Π΄Π²Π΅ Π½ΠΎΠ²Ρ‹Π΅ настройки Π² Ρ„Π°ΠΉΠ»Π΅ php.ini: cli.pager ΠΈ cli.prompt. Π”ΠΈΡ€Π΅ΠΊΡ‚ΠΈΠ²Π° cli.pager Ρ€Π°Π·Ρ€Π΅ΡˆΠ°Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ внСшнюю ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ Π½Π°ΠΏΠΎΠ΄ΠΎΠ±ΠΈΠ΅ less для постраничного просмотра, Π° Π½Π΅ прямого Π²Ρ‹Π²ΠΎΠ΄Π° Π΄Π°Π½Π½Ρ‹Ρ… Π½Π° экран. Настройка cli.prompt Ρ€Π°Π·Ρ€Π΅ΡˆΠ°Π΅Ρ‚ Π·Π°Π΄Π°Π²Π°Ρ‚ΡŒ ΠΏΡ€ΠΈΠ³Π»Π°ΡˆΠ΅Π½ΠΈΠ΅ php > Π½Π° Π²Π²ΠΎΠ΄ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹.

Π’ ΠΈΠ½Ρ‚Π΅Ρ€Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎΠΉ консоли Ρ‚Π°ΠΊΠΆΠ΅ Ρ€Π°Π·Ρ€Π΅ΡˆΠ°Π΅Ρ‚ΡΡ ΡƒΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°Ρ‚ΡŒ настройки Ρ„Π°ΠΉΠ»Π° php.ini Ρ‡Π΅Ρ€Π΅Π· ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ΅ сокращСниС.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ #3 Установка настройки Ρ„Π°ΠΉΠ»Π° 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.
\> Π£ΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ символ ΠΏΡ€ΠΈΠ³Π»Π°ΡˆΠ΅Π½ΠΈΡ. По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ это символ >, Π½ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ, ΠΊΠΎΠ³Π΄Π° ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠ° находится Π²Π½ΡƒΡ‚Ρ€ΠΈ Π½Π΅Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΎΠ³ΠΎ Π±Π»ΠΎΠΊΠ° ΠΈΠ»ΠΈ строки. Π’ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅ символы: ' " { ( >

Π—Π°ΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅:

Π€Π°ΠΉΠ»Ρ‹, ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Ρ‘Π½Π½Ρ‹Π΅ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΎΠΏΡ†ΠΈΠΉ auto_prepend_file ΠΈ auto_append_file ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‚ΡΡ Π² этом Ρ€Π΅ΠΆΠΈΠΌΠ΅ с Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌΠΈ ограничСниями, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ ΠΎΠ±ΡŠΡΠ²Π»Π΅Π½Ρ‹ Π΄ΠΎ ΠΈΡ… использования.

Π˜Π½Ρ‚Π΅Ρ€Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹ΠΉ Ρ€Π΅ΠΆΠΈΠΌ

Π”ΠΎ PHP 8.1.0 ΠΏΡ€ΠΈ нСдоступности модуля readline Π²Ρ‹Π·ΠΎΠ² Ρ„Π°ΠΉΠ»Π° CLI SAPI с ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠΌ -a запускал ΠΈΠ½Ρ‚Π΅Ρ€Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹ΠΉ Ρ€Π΅ΠΆΠΈΠΌ. Π’ этом Ρ€Π΅ΠΆΠΈΠΌΠ΅ прСдполагаСтся, Ρ‡Ρ‚ΠΎ PHP-скрипт ΠΏΠ΅Ρ€Π΅Π΄Π°Π΄ΡƒΡ‚ Ρ†Π΅Π»ΠΈΠΊΠΎΠΌ Ρ‡Π΅Ρ€Π΅Π· стандартный Π²Ρ…ΠΎΠ΄Π½ΠΎΠΉ ΠΏΠΎΡ‚ΠΎΠΊ STDIN, Π·Π°Ρ‚Π΅ΠΌ Π·Π°Π²Π΅Ρ€ΡˆΠ°Ρ‚ Π²Π²ΠΎΠ΄ ΠΊΠΎΠΌΠ±ΠΈΠ½Π°Ρ†ΠΈΠ΅ΠΉ клавиш CTRL +D (Π² POSIX-систСмах) ΠΈΠ»ΠΈ ΠΊΠΎΠΌΠ±ΠΈΠ½Π°Ρ†ΠΈΠ΅ΠΉ CTRL +Z , Π·Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΈΠ΄Ρ‘Ρ‚ клавиша ENTER (Π² ОБ Windows), послС Ρ‡Π΅Π³ΠΎ скрипт обработаСтся. По сути это Ρ‚ΠΎ ΠΆΠ΅ самоС, Ρ‡Ρ‚ΠΎ ΠΈ Π²Ρ‹Π·ΠΎΠ² CLI SAPI Π±Π΅Π· ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° -a. option.

Начиная с PHP 8.1.0 ΠΏΡ€ΠΈ нСдоступности модуля readline Π²Ρ‹Π·ΠΎΠ² CLI SAPI с ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠΌ -a Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ ошибкой.

οΌ‹Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΡ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ 7 notes

up
177
Ryan P ΒΆ
14 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
57
spencer at aninternetpresence dot net ΒΆ
14 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
13
#linuxmint-es ΒΆ
8 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 ΒΆ
15 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
3
John ΒΆ
8 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
2
Gray ΒΆ
6 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
turabgarip at gmail dot com ΒΆ
2 years ago
Note that destructors will not be triggered when exiting interactive shell by any method. (Like CTRL + D, CTRL + Z or CTRL + C).

Since the interactive shell is effectively a continuous runtime, the "end of script" condition is never met for a destructor to run. And exiting the interactive shell is not considered end of script but rather the end of interpreter process. And since the process is dead; it can't run the destructor.

Therefore the only way for a destructor to run is that you remove all the references to the corresponding object. Like:

<?php

class A {
    public function __destructor() {
        // This will never run after ending PHP interactive shell session.
    }
}

$a = new A();

// This is the only way for the destructor to be able to run.
$a = null; // Or;
unset($a);

?>