Интерактивная оболочка с использованием PHP - PullRequest
25 голосов
/ 26 апреля 2011

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

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

Ответы [ 8 ]

38 голосов
/ 26 апреля 2011

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

24 голосов
/ 18 июня 2014

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

$input = fgets(STDIN);
5 голосов
/ 02 апреля 2014

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

php -a

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

$ php -a
Interactive shell

php > 

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

php > $a = 'abcdef';
php > echo strlen($a);
6
2 голосов
/ 14 сентября 2014

Вот расширенный взгляд на это.Я добавил проверку isCLI() на случай, если вы запустите свой скрипт как в 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);
1 голос
/ 01 марта 2013

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

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

1 голос
/ 26 апреля 2011

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

0 голосов
/ 24 марта 2018

Поскольку PHP имеет встроенную unix only функцию 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 ls результат

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 голосов
/ 30 июня 2013

Выезд:

https://github.com/shaneharter/sheldon

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

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

...