Создание гостевой книги на PHP

Практика создания гостевой книги



Создание формы для добавления сообщений

Принятие данных из формы

Решаем проблему F5

Считывание файла

Разбиваем строку по разделителю

Удаление последнего элемента массива

Сортировка сообщений в обратном порядке

Вывод сообщений



Создание формы для добавления сообщений




Создадим файл index.php и создадим в нем форму, которая будет добавлять сообщения. Это будет простейшая гостевая книга, без всяких проверок. Просто научимся как добавлять данные в текстовые файлы и считывать их от туда.

Создаем форму:
- action = "index.php" --- экшеном будет текущий файл;
- method = "post" --- метод передачи данных будет - post;


Чтобы связать поле для ввода имени с ярлыком label указываем id="name";


Файл index.php


-- файл index.php --

<?php
header("Content-type: text/html; charset=utf-8");
error_reporting(-1);
?>


<!doctype html>
<html Lang="en">
<html>
<head>
<meta charset ="UTF-8">
<title>Гостевая книга</title>
</head>
<body>
<!-- Создаем форму -->
<form action = "index.php" method = "post">
<p>
<!-- название поля -->
<label for ="name"> Имя:</label>
<!-- поле для ввода имени -->
<input type ="text" name ="name" id ="name">
</p>
<p>
<!-- название поля -->
<label for ="text"> Текст:</label>
<!-- поле для ввода текста -->
<textarea name = "text" id ="text"></textarea>
</p>
<!-- кнопка -->
<button type ="submit"> Написать </button>
</form>
</body>
</html>





Принятие данных из формы




Далее нам необходимо принять данные из этой формы и сохранить сообщение в текстовом файле.
Для этого проверим, если у нас не пуст массив $_POST, то вызовем некую функцию: save_mess.
Соответственно данную функцию необходимо где-то описать - это будет наша пользовательская функция . Создадим под нее отдельный файл - funcs.php и опишем там нашу функцию save_mess.
Она будет принимать из массива $_POST поля "name" и "text" и формировать из них единую строку. В переменную $str запишем то, что содержиться в $_POST['name'] и то, что содержиться в $_POST['text']. Для того, чтобы они не сливались друг с другом, поставим между ними разделитель, например '|'. Запишем сюда через разделитель еще и дату - date('Y-m-d H:i:s') с нужным нам форматом.

Отделять различные сообщения мы будем с помощью специального разделителя - "\n***",
- где \n - перенос строки.

Далее записываем все в файл gb.txt с помощью функции file_put_contents .
Добавляем в функцию третий параметр - константу FILE_APPEND , чтобы наши сообщения не перезаписывались.


Файл funcs.php


-- файл funcs.php - функция save_mess() --

<?php
function save_mess(){
$str = $_POST['name'] . '|' . $_POST['text'] . '|' . date('Y-m-d H:i:s') . "\n***\n" ;
// записываем все в файл gb.txt с помощью функции file_put_contents
file_put_contents('gb.txt', $str, FILE_APPEND);
}
?>



В индексном файле подключаем наш файл (funcs.php) с помощью функции require_once

Теперь, когда мы отправим данные из формы, сработает условие if(!empty($_POST)) и будет вызвана функция save_mess(), которая получит в одну строку данные $str и запишет эту строку в указанный файл gb.txt


Файл index.php


-- файл index.php --

<?php
header("Content-type: text/html; charset=utf-8");
error_reporting(-1);

require_once 'funcs.php'; // подключаем файл funcs.php

// принятие данных из формы
// если у нас не пуст массив $_POST, то вызовем некую функцию: save_mess
if (! empty ( $_POST )){
save_mess();// пользовательская функция
}
?>


<!doctype html>
<html Lang="en">
<html>
<head>
<meta charset ="UTF-8">
<title>Гостевая книга</title>
</head>
<body>
<form action = "index.php" method = "post">
<p>
<!-- название поля -->
<label for ="name"> Имя:</label>
<!-- поле для ввода имени -->
<input type ="text" name ="name" id ="name">
</p>
<p>
<!-- название поля -->
<label for ="text"> Текст:</label>
<!-- поле для ввода текста -->
<textarea name = "text" id ="text"> </textarea>
</p>

<!-- кнопка -->
<button type="submit"> Написать </button>
</form>
</body>
</html>




Введем в поля данные:


guest01



После отправления сообщения будет создан файл gb.txt и в нем появится первая запись:


Файл gb.txt


-- файл gb.txt --

Андрей|Привет!
Это первое сообщение|2019-05-03 00:35:44
***



Все последующие сообщения будут отделены друг от друга разделителем "***".



Решаем проблему F5




Данные формы заполнены и нам необходимо их сбросить, перезапросив страницу (чтобы избежать повторной отправки формы).

Для этого достаточно произвести редирект (Нужно указать, с помощью функции header, какую страницу хотим мы получить).

Здесь можно просто записать в index.php: header("Location: index.php"), а можем ипользовать дополнительную возможность PHP - можем использовать суперглобальную переменную - массив $_SERVER , и его элемент - php_self , который вернет нам имя текущего скрипта, то есть, мы сделаем редирект на этот же самый скрипт. Используя $_SERVER['PHP_SELF'], мы делаем наш скрипт чуть более универсальным. Можно так-же заменить экшен в форме.

В индексном файле допишем: header("Location: {$_SERVER['PHP_SELF']} ");

Обязательно не забываем об exit или die, чтобы код, который идет ниже, не выполнялся.


Файл index.php


-- файл index.php --

<?php
..........
..........
..........
if (! empty ( $_POST )){
save_mess();
// редирект на этот же самый скрипт
header ("Location: {$_SERVER ['PHP_SELF' ]}");
exit;
}
..........
..........
..........
?>




Считывание файла




Для этого создадим в индексном файле переменную $messages в которую и будем считывать данные с помощью пользовательской функции get_mess


Файл index.php


-- файл index.php --

<?php
..........
..........
..........
if (! empty ( $_POST )){
save_mess();
// редирект на этот же самый скрипт
header ("Location: {$_SERVER ['PHP_SELF' ]}");
exit;
}
$messages = get_mess();
//echo $messages = get_mess();
..........
..........
..........
?>



Функция get_mess() - эта функция будет просто вызывать функцию file_get_contents и возвращать результат.


Файл funcs.php


-- файл funcs.php - функция get_mess() --

<?php
..........
..........
..........
function get_mess(){
// возвращаем результат работы функции file_get_contents
return file_get_contents( 'gb.txt' );
}
?>
После обновления страницы получаем:
Андрей|Привет! Это первое сообщение|2019-05-03 00:45:18 *** Вася|Привет! Это второе
сообщение|2019-05-03 00:45:48 *** Петя|)))))|2019-05-03 21:32:13 ***




Разбиваем строку по разделителю




Данные получены, но они получены в одну строку.

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

В переменную $messages мы вернем результат работы пользовательской функции array_mess(), которая будет фактически из строки получать массив.

Файл index.php


-- файл index.php --

<?php
..........
..........
..........
$messages = get_mess();
$messages = array_mess($messages);
..........
..........
..........
?>



Опишем функцию array_mess() в файле funcs.php. В качестве параметра она принимает строку с сообщениями $messages.

С помощью функции explode разобьем строку по разделителю.

Первым параметром будет наш разделитель ("\n***\n") - двойные кавычки - обязательны, потому что есть символы переноса строк.

Вторым параметром будет наша строка - $messages.

Далее вернем $messages и распечатаем сообщения.


Напишем еще одну пользовательскую функцию, для распечатки массива в форматированном виде print_arr(). Параметром она будет принимать массив $arr .


Файл funcs.php


-- файл funcs.php - функции array_mess() и print_arr() --

<?php
..........
..........
..........
function array_mess($messages){
$messages = explode("\n***\n" , $messages);
return $messages ;
}

function print_arr($arr){
echo '< pre>' . print_r($arr , true) . '</pre>';
}
?>



Функция print_r() имеет еще второй параметр, true - применение этого параметра позволяет сразу не выводить, а буферизировать данные.

Вызываем функцию print_arr($arr) в индексном файле:


Файл index.php


-- файл index.php --

<?php
..........
..........
..........
$messages = get_mess();
$messages = array_mess($messages);
print_arr ($messages);
..........
..........
..........
?>
После обновления страницы получаем:
Array
(
[0] => Андрей|Привет!
Это первое сообщение|2019-05-03 22:51:24
[1] => Вася|Привет!
Это второе сообщение|2019-05-03 22:51:54
[2] => Петя|)))))|2019-05-03 22:52:12
[3] => ------------------------------ пустой элемент массива
)




Удаление последнего элемента массива




Чтобы удалить последний ненужный элемент массива воспользуемся функцией array_pop()

- данная функция возвращает последний элемент массива и удаляет его сразу же из массива.


Файл funcs.php


-- файл funcs.php - функции array_mess() --

<?php
..........
..........
..........
function array_mess($messages){
$messages = explode("\n***\n", $messages);
array_pop($messages); // убираем последний элемент массива
return $messages ;
}
..........
..........
..........
?>



После обновления страницы последний (пустой) элемент массива будет удален.



Сортировка сообщений в обратном порядке




С помощью функции array_reverse() переворачиваем массив:


Файл funcs.php


-- файл funcs.php - функции array_mess() --

<?php
..........
..........
..........
function array_mess($messages){
$messages = explode("\n***\n", $messages);
array_pop($messages); // убираем последний элемент массива
return array_reverse($messages); // переварачиваем массив
}
..........
..........
..........
?>
выведет:
Array
(
[0] => Петя|)))))|2019-05-03 22:56:36
[1] => Вася|Привет!
Это второе сообщение|2019-05-03 22:56:24
[2] => Андрей|Привет!
Это первое сообщение|2019-05-03 22:56:00
)




Вывод сообщений




Проходим по массиву $messages в цикле и выводим наши сообшения.

В индексном файле проверяем:
если у нас не пусто if(!empty) переменная $messages(массив сообщений), тогда мы
будем выводить эти сообщения. Для этого запускаем цикл foreach, проходимся по $messages ,
берем каждое сообщение в переменную $message и выводим то, что там находится.

А там находиться, например, строка: Петя|)))))|2019-05-04 22:55:33 - - в получаемых строках есть также разделители - "|", соответственно эти строки мы можем также разбить в массив, в котором будет три элемента: имя, текст сообщения и дата.
В тегах div класса "messages" заключим каждое конкретное сообщение.

Напишем еще одну пользовательскую функцию: get_format_message() в файле funcs.php, которая будет разбивать cтроку по разделителю "|".

В переменную $message (index.php) мы вернем результат работы функции get_format_message(), в качестве параметра она принимает $message . Можно было бы вызвать функцию explode(), но функция get_format_message() может в дальнейшем разрастись и было бы правильно чтобы она была вынесена.


Выводим полученные наши данные используя короткую запись: <?=$message[0]?> - это тоже самое, что и <?php echo $message[0]; ?> :

- <?=$message[0]?> - Автор
- <?=$message[2]?> - Дата
- <?=nl2br($message[1])?> - сообщение ( nl2br - для многострочного текста)
- htmlspecialchars - экранируем тэги


Файл funcs.php


-- файл funcs.php - функции get_format_message() и print_arr() --

<?php
..........
..........
..........
function get_format_message($message){
return explode('|', $message);
}
function print_arr($arr){
echo '< pre>' . print_r($arr, true) . '</pre>';
}
?>



Файл index.php


-- файл index.php --

<?php
..........
..........
..........
print_arr ($messages);
?>


<!doctype html>
<html Lang="en">
<html>
<head>
<meta charset ="UTF-8">
<title>Гостевая книга</title>
</head>
<body>
<!-- Форма -->
<form action = "index.php" method = "post">
<p>
<!-- название поля -->
<label for ="name"> Имя:</label>
<!-- поле для ввода имени -->
<input type ="text" name="name" id ="name">
</p>
<p>
<!-- название поля -->
<label for ="text" > Текст:</label>
<!-- поле для ввода текста -->
<textarea name = "text" id="text" > </textarea>
</p>
<!-- кнопка -->
<button type="submit"> Написать </button>
</form>

<hr>

<?php if (! empty ($messages)): ?>
<!-- проходим по массиву $messages в цикле и выводим наши сообшения -->
<?php foreach ($messages as $message) : ?>
<!-- возвращает, разбитую в массив строку -->
<?php $message = get_format_message($message); //print_r($message) ?>
<!-- выводим полученные наши данные -->
<div class= "messages">
<hr>
<p> Автор: <?= $message[0] ?> | Дата: <?= $message[2] ?> </p>
<div <?= nl2br ( htmlspecialchars ($message[1]) ) ?> </div>
<hr>
</div
<?php endforeach; ?>
<?php endif ?>
</body>
</html>




В результате получим:


guest02



Структура файлов урока


php22.png







Наверх Наверх