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