Readline add history: примеры (PHP)
readline_add_history(string $prompt): boolФункция readline_add_history является частью модуля Readline в PHP. Она используется для добавления строки в историю ввода. История сохраняется между вызовами скрипта в рамках одной сессии интерпретатора, если используется встроенный CLI-сервер или интерактивный режим.
Эта функция применяется в интерактивных командных строковых (CLI) приложениях на PHP для запоминания ранее введённых команд или данных, что позволяет пользователю перемещаться по ним с помощью клавиш со стрелками вверх и вниз.
Функция принимает один обязательный параметр:
- string $line - Строка, которую необходимо добавить в историю. Строка должна заканчиваться на новой строке, как правило, это пользовательский ввод, полученный через
readline().
Функция возвращает true в случае успешного выполнения.
<?php
// Включаем поддержку readline, если не включена автоматически
if (!function_exists('readline')) {
dl('readline.so'); // Для Unix-систем, может потребоваться
}
$command = readline('Введите команду: ');
readline_add_history($command);
echo 'Команда добавлена в историю.';
?>Введите команду: echo 'Hello' Команда добавлена в историю.
<?php
$inputs = [];
for ($i = 0; $i < 3; $i++) {
$input = readline('Элемент ' . ($i+1) . ': ');
$inputs[] = $input;
readline_add_history($input);
}
echo 'Введённые данные: ' . implode(', ', $inputs);
?>Элемент 1: Apple Элемент 2: Banana Элемент 3: Cherry Введённые данные: Apple, Banana, Cherry
Прямых аналогов readline_add_history в стандартной библиотеке PHP нет, так как она специфична для модуля Readline. Однако для чтения ввода в CLI-среде можно использовать:
- fgets(STDIN) - Читает строку из стандартного ввода. Не поддерживает историю, автодополнение или управляющие последовательности. Подходит для простейшего ввода.
- stream_get_line(STDIN, length, "\n") - Более контролируемое чтение строки из потока.
- Библиотеки вроде "php-school/cli-menu" - Предоставляют полноценные интерактивные меню с историей и другими функциями, но требуют установки.
readline_add_history предпочтительнее, когда нужна именно история ввода в нативном интерактивном CLI-приложении без сторонних зависимостей.
import readline
command = input('Введите команду: ')
readline.add_history(command)
print(f'Добавлено: {command}')Введите команду: import os Добавлено: import os
В Python модуль readline предоставляет почти идентичный интерфейс. Он часто доступен по умолчанию в Unix-подобных системах.
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
historySize: 50
});
rl.question('Введите что-то: ', (answer) => {
// История управляется автоматически интерфейсом
console.log(`Вы ввели: ${answer}`);
console.log('История:', rl.history);
rl.close();
});Введите что-то: console.log(1) Вы ввели: console.log(1) История: [ 'console.log(1)' ]
В Node.js история обычно управляется автоматически объектом интерфейса readline, но можно получить к ней доступ через свойство .history.
В MySQL нет встроенной истории ввода на уровне функций языка, так как это СУБД. История команд обычно предоставляется клиентским приложением (например, mysql cli, который использует GNU Readline или libedit).
<?php
// Если модуль readline не установлен или отключён
$line = 'test';
$result = @readline_add_history($line);
if (!$result && !function_exists('readline_add_history')) {
echo 'Ошибка: Модуль readline не доступен.';
}
?>Ошибка: Модуль readline не доступен.
<?php
// PHP 8 выдаст TypeError
readline_add_history(12345);
?>Fatal error: Uncaught TypeError: readline_add_history(): Argument #1 ($line) must be of type string, int given...
<?php
// При запуске через веб-сервер (не CLI)
if (php_sapi_name() !== 'cli') {
die('Эта функция работает только в CLI-режиме.');
}
readline_add_history('test');
?>Эта функция работает только в CLI-режиме.
Для функции readline_add_history значительных изменений в поведении в последних основных версиях PHP (5.x, 7.x, 8.x) не зафиксировано. Основные относящиеся к модулю изменения:
- PHP 8.0.0: Параметр
$lineтеперь имеет явный типstring. Передача нестрокового значения вызываетTypeError. Ранее неявное преобразование типов могло приводить к неожиданным результатам. - PHP 5.1.0: Модуль Readline был обновлён для использования библиотеки libedit. Совместимость с GNU Readline сохраняется, но некоторые расширенные возможности могут отличаться.
Рекомендуется всегда проверять доступность модуля, особенно в кросс-платформенных проектах.
<?php
$historyFile = sys_get_temp_dir() . '/php_readline_history.txt';
// Загружаем историю из файла, если существует
if (file_exists($historyFile)) {
readline_read_history($historyFile);
}
while (true) {
$line = readline('> ');
if ($line === 'exit') {
break;
}
if (trim($line) !== '') {
readline_add_history($line);
echo 'Вы сказали: ' . $line . PHP_EOL;
}
}
// Сохраняем историю в файл
readline_write_history($historyFile);
echo 'История сохранена. До свидания!' . PHP_EOL;
?>> echo 1 Вы сказали: echo 1 > $a = 10 Вы сказали: $a = 10 > exit История сохранена. До свидания!
<?php
function addToHistoryIfValid($line) {
// Не добавляем пустые строки или команды, начинающиеся с пробела
if (trim($line) === '' || strpos($line, ' ') === 0) {
return false;
}
return readline_add_history($line);
}
$input = readline('Введите команду (пробелы в начале игнорируются): ');
if (addToHistoryIfValid($input)) {
echo 'Добавлено.';
} else {
echo 'Не добавлено (фильтр).';
}
?>Введите команду (пробелы в начале игнорируются): secret Не добавлено (фильтр).
<?php
// Функция автодополнения
function autoComplete($partial, $index) {
$commands = ['list', 'delete', 'update', 'exit', 'help'];
return $commands[$index] ?? null;
}
readline_completion_function('autoComplete');
// Добавляем несколько команд в историю для демонстрации
readline_add_history('list');
readline_add_history('help');
$cmd = readline('Команда (попробуйте нажать Tab): ');
readline_add_history($cmd);
echo 'Выполняем: ' . $cmd . PHP_EOL;
// Показать всю текущую историю
$hist = readline_list_history();
echo 'Текущая история: ' . implode(', ', $hist);
?>Команда (попробуйте нажать Tab): li<Tab> // Пользователь нажимает Tab Команда (попробуйте нажать Tab): list // Автодополнение Выполняем: list Текущая история: list, help, list