Интерактивная оболочка с использованием переполнения стека

Просто интересно, возможно ли создать интерактивную оболочку, используя только PHP. Я имею в виду что-то вроде вас с базами данных, Python и т. Д.

Если это так, как?

23

Решение

Да, это возможно. Для того, чтобы быть интерактивным, программа должна быть в состоянии ждать и читать пользовательский ввод из 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), вы могли бы использовать няни.

37

Другие решения

Поскольку этот вопрос был задан и получен ответ, лучшее решение было добавлено в PHP. Во всех последних версиях PHP вы можете легко получить пользовательский ввод следующим образом:

$input = fgets(STDIN);
22

Насколько я понимаю ваш вопрос, вы просто хотите, чтобы интерпретатор PHP запускался из командной строки, чтобы вы могли оценить любой набранный вами код PHP. Я постоянно использую эту функцию Python для тестирования фрагментов кода. В этом случае я считаю, что ответ, который вы ищете, заключается в выполнении (из командной строки):

php -a

Если предположить, что PHP находится на вашем пути, это приведет вас к интерпретатору PHP, как это происходит с моим:

$ php -a
Interactive shell

php >

Оттуда вы можете начать оценивать произвольные выражения PHP и увидеть результаты:

php > $a = 'abcdef';
php > echo strlen($a);
6
5

Вот расширенный взгляд на это. Я добавил 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);
2

Из вопроса не совсем ясно, хотите ли вы СОЗДАТЬ оболочку, используя только PHP, или хотите, чтобы интерактивная оболочка обрабатывала команды PHP. Я собираюсь предположить последнее, и в этом случае один пример phpsh который, по-видимому, был создан на Facebook, но написан на python.

1

Я знаю, что спрашивающий не хотел второй вариант, но для тех, кто хотел второй вариант, как я, в дополнение к phpshPHP также имеет это собственная оболочка:

Просто беги php -a,

1

Проверять, выписываться:

https://github.com/shaneharter/sheldon

Начать довольно легко. Он включает в себя библиотеки Symfony2 и Zend Framework, которые выполняют большую часть работы с консольным вводом-выводом, и предоставляет вам абстракцию более высокого уровня, построенную вокруг объектов Command (с маршрутами регулярных выражений) и контекстов (которые содержат неизменяемое состояние).

Одна из вещей, которые мне нравятся, это то, что «из коробки» ваше приложение может запускаться либо как интерактивная оболочка, либо как стандартный скрипт, который вы можете запустить из командной строки, указать команду, передать любые аргументы, и когда команда приложение завершено.

0

Так как 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());

Очень полезно создавать действительно сложные вещи!

http://php.net/manual/en/function.readline.php

0
По вопросам рекламы [email protected]