Ну, это напоминает мне много вещей, которые я делал много лун назад, когда я только начал программировать За исключением того, что я начал задавать вопросы по математике. Написание программы типа ELIZA - довольно сложное дело для новичка!
Очевидно, вы пока не хотите писать удостоенный наград интерфейс чата, ну, я надеюсь, что нет, поскольку это масштабное исследование. Но я постараюсь привести несколько примеров PHP, которые покажут вам, как выполнить несколько шагов, которые вы хотите предпринять, и немного проясните шаги, которые вы предприняли.
Длинный учебник, приготовьтесь ...
Сначала давайте очистим существующий код.
Я предполагаю, что из последней строки этого файла вы используете какой-то генератор HTML или пытаетесь? $h->endpage();
, это на самом деле никогда не используется, так как вы часто используете exit;
, что завершает сценарий в том месте, где он присутствует. Вам не нужно использовать это в конце блока if, если вы не хотите, чтобы программа заканчивалась в этой точке. Программа продолжится после закрывающей скобки }
до следующего оператора.
Я вижу, вы часто используете echo
и print
в своем коде. echo
необходим для записи переменных на HTML-страницу, но есть лучшие способы сделать основную HTML-страницу, которая разделяет код и HTML, так что вы можете сделать более четкую работу в обоих случаях. Теги, которые начинают и заканчивают вашу страницу PHP, <?php ?>
, могут использоваться в любом месте страницы для «взлома» и «разрыва» кода. Внутри скобки, PHP, снаружи, HTML.
например.
<?php
// This is my PHP program
// read the question variable from the Form data
// the form was "post"ed, so we check $_POST
// $_POST is an array (a list) of all the variables sent by the form
$question = strtolower($_POST['question']);
if (empty($question)) {
// no question, close PHP and start HTML, show the form
?>
<form action="responder002.php" method="POST">
Question: <input type="text" name="question"> <input type="submit" value="Ask">
</form>
<?php
// back in PHP, if the question was not empty deal with the question
} else {
// try and find an answer
if ($question == 'hello' || $question == 'hi') {
// hello-type question found
$answerp = "Hello, how are you?";
} else if ($question == "fine" || $question == "fine thanks") {
// or a fine-type question
$answerq = "I am glad to hear you are fine.";
} else {
// "else" on its own, no question identified so we do not know
$answerp = "Sorry, I do not know the answer.";
}
// close PHP and display the answer
// note: opening and closing PHP briefly where we want a variable
// using "echo" to output the variable contents
?>
<h2>Answer</h2>
<p><i>You asked me:</i> <?php echo $question; ?></p>
<p><i>I replied:</i> <?php echo $answerp; ?></p>
<?php
// close the else opening bracket from above
}
// and we are done, close PHP
?>
Как только у нас появится этот базовый метод ответа на вопрос и ответ, мы можем перейти к тому, чтобы сделать его более содержательным.
Вы говорите, что хотите сохранить список слов, которые были замечены, и продолжаете добавлять к нему, когда появляются новые слова. Предположительно, чтобы вы могли вручную посмотреть на то, что спрашивают, и написать новые ответы; или у тебя есть другая мотивация?
Однако вы храните данные, если вы проверяете и добавляете их, это своего рода база данных. Вы можете использовать текстовый файл для хранения данных, если вы можете выбрать метод или если данные сложны, большинству программистов нужна подходящая система базы данных, где записи, содержащие множество полей, могут быть легко сохранены.
На данный момент предположим, что вы хотите использовать текстовые файлы.
На этапе определения того, как вы будете хранить слова, мой совет, чтобы все было просто, - одно слово в строке.
Существует много способов чтения файлов, учитывая, что нам нужно по одному слову в строке, возможно, наиболее удобный и простой способ для команды file()
.
$words = file("words.txt", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
Эта команда читает в целом words.txt
, пропуская все пустые строки и не сохраняя ни одно из окончаний строк (каждая строка в файле заканчивается символом новой строки или символами, передавая опцию игнорирования новой строки функции, сообщает PHP не хранить их.
$words
теперь представляет собой массив каждой строки в файле, список в порядке их появления в файле.
Чтобы проверить, есть ли уже слово в файле, мы можем использовать функцию in_array()
, мы хотим знать, находится ли проверяемое слово в файле. Итак, мы можем сказать:
if (!in_array($currentWord, $words)) {
// add $currentWord to file
}
Символ !
означает , а не . Так как же добавить слово в файл? Ну, есть еще одна функция с именем file_put_contents()
(если вы используете версию PHP старше, чем v5, то этой функции не существует, скажите мне, и я покажу вам более старый и более сложный метод). file_put_contents()
требует от нас ставить символ новой строки после каждого слова, чтобы завершить строку, поэтому мы объединяем "\n"
с каждым словом.
if (!in_array($currentWord, $words)) {
file_put_contents("words.txt", $currentWord . "\n", FILE_APPEND | LOCK_EX);
}
Флаги FILE_APPEND
и LOCK_EX
сообщают функции о добавлении в файл в конце, а не о воссоздании файла с самого начала и блокировании файла исключительно при этом, чтобы никто другой не мог записать в файл пока мы делаем это.
Теперь все это очень хорошо для одного слова, $currentWord
, но как нам пройтись по каждому слову в вопросе?
Первый шаг - разделить вопрос на слова. Есть несколько способов сделать это, но упрощенная команда для этой цели - explode()
.
explode()
берет строку или блок текста и разделяет их, используя указанный разделитель, в список (массив) отдельных фрагментов.
$questionWords = explode(" ", $question);
Предполагая, что каждое слово отделено пробелом, это вернет массив слов. explode()
- простая функция, которая разбивает каждый пробел, поэтому, если у вас есть два пробела, он разделит это и скажет, что между пробелами есть пустая строка explode("-", "hello--world")
(используя тире для пробелов) даст список ('hello', '', 'world')
, например, из-за двойной тире. Чтобы избавиться от пустых «слов», мы можем поместить фильтр в разнесение, чтобы удалить пустые записи.
$questionWords = array_filter(explode(" ", $question));
Теперь у нас есть наш список слов из вопроса, как мы можем объединить его с чтением файла слов и сохранением новых слов? С петлей.
$words = file("words.txt", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$questionWords = array_filter(explode(" ", $question));
foreach ($questionWords as $currentWord) {
if (!in_array($currentWord, $words)) {
file_put_contents("words.txt", $currentWord . "\n", FILE_APPEND | LOCK_EX);
}
}
foreach
перебирает каждое слово в $questionWords
, устанавливая переменную $currentWord
каждый раз посредством кода между фигурными скобками.
Это будет работать, но очень неэффективно, так как файл должен открываться, записываться и закрываться для каждого нового слова. Было бы лучше составить список новых слов и добавить их все сразу. Для этого мы создаем пустой массив (список) новых слов и добавляем в него новые слова, когда находим их.
$words = file("words.txt", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$questionWords = array_filter(explode(" ", $question));
$newWords = array();
foreach ($questionWords as $currentWord) {
if (!in_array($currentWord, $words)) {
// add new word to $newWords
$newWords[] = $currentWord;
}
}
// write all the new words at once
file_put_contents("words.txt", implode("\n", $newWords), FILE_APPEND | LOCK_EX);
Новые слова добавляются все сразу, взяв список в $newWords
и сделав противоположное explode()
, которое разбило строку на отдельные слова, мы implode()
список слов в один фрагмент текста, каждое слово отделено новой строкой "\n"
.
Я думаю, что этого достаточно, чтобы немного разобраться, внимательно прочитать его, ознакомиться с концепциями и дать мне знать, если вы хотите продолжить.