Интерактивная оболочка с использованием PHP
Просто интересно, возможно ли создать интерактивную оболочку, используя только PHP. Я имею в виду что-то вроде вас с базами данных, Python и т. Д.
Если это так, как?
8 ответов
Да, это возможно. Для того, чтобы быть интерактивным, программа должна быть в состоянии ждать и читать вводимые пользователем данные со стандартного ввода. В PHP вы можете читать из стандартного ввода, открыв дескриптор файла для '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. Во всех последних версиях 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
Вот расширенный взгляд на это. Я добавил isCLI()
проверьте, запускаете ли вы свой скрипт как в CLI, так и на веб-сервере. В противном случае сервер может зацикливаться, используя мою функцию. Это решение будет запрашивать пользователя, проверять ввод и повторно запрашивать фиксированный ввод в случае необходимости. я 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);
Поскольку PHP имеет встроенную функцию только для Unix 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
результат
h
"Привет"
q
выход
ctrl+c
выход.
ctrl+d
с пустым вводом перейдите к следующей последовательности. "Спасибо". $user
определено и пусто, без ошибок.
ctrl+d
с некоторыми входными данными: никаких действий. Все еще жду ввода.
ctrl+m
Продолжить и принять текущий ввод в $user
,
ctrl+j
Продолжить и принять текущий ввод в $user
такое же поведение как ctrl+m
,
Return
перейти к следующей последовательности "Спасибо". $user
может оставаться пустым, без ошибок.
ctrl+z
может использоваться для отмены цикла и перехода к верхнему. $user
будет сброшен, если переменная не определена в этой области.
В зависимости от ввода мы можем определить пустые значения, используя!empty
или делать больше хирургических тестов (ответ readline может быть много символов).
$user
можно проверить с !isset
если еще не спросил.
Также есть встроенный readline_add_history()
сохранить пользовательский ввод в объект, где значения могут быть получены непосредственно по их имени (приятно для ясности кода):
readline_add_history($user);
print_r(readline_list_history());
print_r(readline_user());
Очень полезно создавать действительно сложные вещи!
Из вопроса не совсем ясно, хотите ли вы СОЗДАТЬ оболочку, используя только PHP, или хотите, чтобы интерактивная оболочка обрабатывала команды PHP. Я собираюсь предположить последнее, и в этом случае одним из примеров является phpsh, который, очевидно, был создан на Facebook, но написан на python.
Я знаю, что спрашивающий не хотел второй вариант, но для тех, кто хотел второй вариант, как я, в дополнение к phpsh
PHP также имеет свою собственную оболочку:
Просто беги php -a
,
Проверять, выписываться:
https://github.com/shaneharter/sheldon
Начать довольно легко. Он включает в себя библиотеки Symfony2 и Zend Framework, которые выполняют большую часть работы с консольным вводом-выводом, и предоставляет вам абстракцию более высокого уровня, построенную вокруг объектов Command (с маршрутами регулярных выражений) и контекстов (которые содержат неизменяемое состояние).
Одна из вещей, которые мне нравятся, это то, что "из коробки" ваше приложение может запускаться как интерактивная оболочка или как стандартный скрипт, который вы можете запустить из командной строки, указать команду, передать любые аргументы, и когда команда приложение завершено.