Просто интересно, возможно ли создать интерактивную оболочку, используя только PHP. Я имею в виду что-то вроде вас с базами данных, Python и т. Д.
Если это так, как?
Да, это возможно. Для того, чтобы быть интерактивным, программа должна быть в состоянии ждать и читать пользовательский ввод из 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), вы могли бы использовать няни.
Поскольку этот вопрос был задан и получен ответ, лучшее решение было добавлено в 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, или хотите, чтобы интерактивная оболочка обрабатывала команды PHP. Я собираюсь предположить последнее, и в этом случае один пример phpsh который, по-видимому, был создан на Facebook, но написан на python.
Я знаю, что спрашивающий не хотел второй вариант, но для тех, кто хотел второй вариант, как я, в дополнение к phpsh
PHP также имеет это собственная оболочка:
Просто беги php -a
,
Проверять, выписываться:
https://github.com/shaneharter/sheldon
Начать довольно легко. Он включает в себя библиотеки Symfony2 и Zend Framework, которые выполняют большую часть работы с консольным вводом-выводом, и предоставляет вам абстракцию более высокого уровня, построенную вокруг объектов Command (с маршрутами регулярных выражений) и контекстов (которые содержат неизменяемое состояние).
Одна из вещей, которые мне нравятся, это то, что «из коробки» ваше приложение может запускаться либо как интерактивная оболочка, либо как стандартный скрипт, который вы можете запустить из командной строки, указать команду, передать любые аргументы, и когда команда приложение завершено.
Так как 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());
Очень полезно создавать действительно сложные вещи!