Я отвечу ужасным, нарисованным рукой комиком. Второе изображение является причиной того, что result
является undefined
в вашем примере кода.
Да, это возможно. Чтобы быть интерактивным, программа должна быть в состоянии ждать и читать входные данные пользователя из stdin . В PHP вы можете прочитать из stdin , открыв дескриптор файла до 'php://stdin'
. Взяв из ответ на другой вопрос , вот пример интерактивной подсказки пользователя в PHP (конечно, если вы запускаете из командной строки):
echo "Continue? (Y/N) - ";
$stdin = fopen('php://stdin', 'r');
$response = fgetc($stdin);
if ($response != 'Y') {
echo "Aborted.\n";
exit;
}
Конечно, чтобы получить полную строку ввода, а не один символ, вам понадобится fgets()
вместо fgetc()
. В зависимости от того, что сделает ваша программа / оболочка, вся программа может быть структурирована как один большой непрерывный цикл. Надеюсь, это даст вам представление о том, как начать работу. Если вы хотите получить действительно фантазию (псевдо-GUI) CLI, вы можете использовать ncurses .
Поскольку PHP имеет встроенную функцию unix readline()
, чтобы сделать именно это, оставляя здесь следующие примечания.
Мы можем использовать и удерживать результат readline
в var.
#!/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
выйти
ctrl+c
выйти.
ctrl+d
с пустым входом, продолжить следующая последовательность. "Благодаря". $user
определен и пуст, нет ошибки.
ctrl+d
с некоторым вводом: никаких действий.
ctrl+m
Продолжить и взять текущий вход в $user
.
ctrl+j
Продолжить и взять текущий вход в $user
, такое же поведение, как и ctrl+m
.
Return
перейти к следующей последовательности «Спасибо». $user
может оставаться пустым, без ошибок.
ctrl+z
может использоваться для отмены цикла и перехода к верхнему. $user
не будет отменено, если var не определен в этой области.
В зависимости от ввода мы можем определить пустые значения с помощью !empty
или сделать больше хирургических тестов (ответ на readline может быть много символов).
$user
можно проверить с помощью !isset
, если еще не спросил .
Существует также встроенный readline_add_history()
для хранения пользовательского ввода в объект, где значения могут быть получены непосредственно по их имени (Nice для четкости кода):
readline_add_history($user);
print_r(readline_list_history());
print_r(readline_user());
Очень полезно создавать настоящие сложные вещи!
Поскольку этот вопрос задан и дан ответ, в PHP добавлено лучшее решение. Во всех последних версиях PHP вы можете легко получить пользовательский ввод:
$input = fgets(STDIN);
Как я понимаю ваш вопрос, вы просто хотите, чтобы интерпретатор PHP запускался в командной строке, чтобы вы могли оценить любой введенный вами PHP-код. Я использую эту функцию Python все время, чтобы проверить фрагменты кода. В этом случае я считаю, что ответ, который вы ищете, должен выполняться (из командной строки):
php -a
Предполагая, что PHP находится на вашем пути, это приведет вас к интерпретатору PHP, как это делает на моем:
$ php -a
Interactive shell
php >
Оттуда вы можете начать оценивать произвольные выражения PHP и видеть результаты:
php > $a = 'abcdef';
php > echo strlen($a);
6
Я знаю, что вопросику не нужен второй вариант, но для тех, кто хотел второй вариант, как я, в дополнение к phpsh
, PHP также имеет собственную оболочку :
Просто запустите php -a
.
Неясно, хотите ли вы CREATE shell использовать только PHP, или хотите, чтобы интерактивная оболочка обрабатывала команды PHP. Я собираюсь принять последнее, и в этом случае один пример - phpsh , который, по-видимому, был создан в Facebook, но написан на python.
Отъезд:
https://github.com/shaneharter/sheldon
Довольно легко начать. Он включает библиотеки Symfony2 и Zend Framework, которые выполняют большую часть основной работы ввода-вывода консоли и предоставляют абстракцию более высокого уровня, построенную вокруг объектов Command (с маршрутами регулярных выражений) и контекстов (которые содержат неизменяемое состояние).
Одна из вещей, которые мне нравятся, заключается в том, что «из коробки» ваше приложение может работать как интерактивная оболочка, или как стандартный скрипт, который вы можете запустить из командной строки, указать команду, передать любые аргументы, и когда команда завершена, приложение завершает работу.
Вот расширенный подход к этому. Я добавил проверку isCLI()
, если вы запустили свой скрипт как в CLI, так и на веб-сервере. В противном случае сервер мог бы использовать мою функцию. Это решение будет запрашивать у пользователя, проверять ввод и повторно запрашивать пользователя для фиксированного ввода, если это необходимо. I rtrim()
, потому что, если пользователь использует возврат, чтобы отправить свою запись, которая может быть добавлена к записи. Проверка не нужна, просто не передавайте функцию в этом случае.
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);