Создание гостевой книги на PHP с использованием базы данных

Практика создания гостевой книги с использованием БД



1 Подключение к базе данных.

2 Принятие данных из формы и реализация сохранения сообщений .

Функция для экранирования данных.

3 Считывание и вывод данных.



Переделаем гостевую книгу, которая работает на файлах (из раздела "Практика создания гостевой книги") под работу с базой данных.


База данных у нас есть - gb, таблица с сообщениями в ней есть - таблица gb


mysql9




Нам необходимо реализовать добавление и сохранение записей в эту таблицу, и вывод записей этих сообщений из этой таблицы.


Файл 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>





Подключение к базе данных




Создадим отдельный файл - connect.php . В нем будет храниться подключение к базе данных:
- подключение: $db = @mysqli_connect('localhost', 'root', '', 'gb'),
- если подключение не удалось, тогда пишем ошибку соединения: or die('Ошибка соединения с БД'),
- устанавливаем кодировку: mysqli_set_charset($db, "utf8") or die ('Не установлена кодировка').
Подключим этот файл в индексном файле: require_once 'connect.php' .


Файл connect.php


-- файл connect.php --

<?php
// Подключение к базе данных
$db = @ mysqli_connect( 'localhost' , 'root' , '', 'gb' ) or die ( 'Ошибка соединения с БД');

if (! $db ) die ( mysqli_connect_error());

// Установка кодировки соединения
mysqli_set_charset( $db, "utf8" ) or die ( 'Не установлена кодировка' );
?>



Файл index.php


-- файл index.php --

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

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


<!doctype html>
<html Lang="en">
...
...
...
</html>





Принятие данных из формы и реализация сохранения сообщений




Далее нам необходимо принять данные из этой формы и сохранить сообщение в таблице gb . Сохранять сообщения будем при помощи пользовательской функции save_mess() (из файла funcs.php). Для этого нам необходим индификатор соединения $db .

Поскольку переменные внутри функции не видны, возьмем ее из глобальной области видимости - global $db .

Далее составим запрос, в котором мы будем что-то вставлять в таблицу базы данных gb:
$query = "INSERT INTO gb (name, text) VALUES ('$name', '$text')" ;
- name, text - поля, и туда вставляем значения $name, $text .

Переменные $name, $text нам необходимо взять из массива $_POST. Поскольку эти данные мы получаем от пользователя, экранируем их функцией mysqli_real_escape_string(), причем каждое текстовое поле():
$name = mysqli_real_escape_string($db, $_POST['name']);
$text = mysqli_real_escape_string($db, $_POST['text']);

- каждое текстовое поле мы должны обрабатывать данной функцией, если не используютя подготовленные выражения,
- если же это числовые данные, то их нужно привести к числовому типу, например: $id = (int)$_POST['$id'] - если мы принимаем некий $id из массива $_POST, то мы должны привести его явно к числовому типу
(int).
Далее выполняем запрос: mysqli_query($db, $query); (без проверки - выполнился он успешно или нет).


Файл funcs.php


-- файл funcs.php --

<?php
function save_mess (){
// переменная $db (индификатор соединения),
// взятая из глобальной области видимости (global)
global $db ;

// переменные $name, $text берем из массива $_POST и экранируем их
// функцией mysqli_real_escape_string

$name = mysqli_real_escape_string($db, $_POST['name']);
$text = mysqli_real_escape_string($db, $_POST['text']);

// составляем запрос
$query = "INSERT INTO gb (name, text) VALUES ('$name', '$text')";

// выполняем запрос (без проверки)
mysqli_query($db, $query);
}
?>



Подключаем файл funcs.php в индексном файле: require_once 'funcs.php' .
Теперь, когда мы отправим данные из формы, сработает условие if(!empty($_POST)) и будет вызвана функция save_mess , которая эти данные сохранит.
Для решения проблемы 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
header("Content-type: text/html; charset=utf-8 ");
error_reporting(-1);

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

// принятие данных из формы
// если у нас не пуст массив $_POST, то вызовем некую функцию: save_mess
if (! empty ($_POST )){
save_mess ();
// производим редирект
header ("Location: {$_SERVER['PHP_SELF']}");
exit ;
}
?>


<!doctype html>
<html Lang="en">
...
...
...
</html>




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


guest1



Жмем "написать", проверяем таблицу gb - в таблице появилась новая запись.


guest2




Функция для экранирования данных




Если данных много, можно написать функцию для их экранирования. Например:
Создадим функцию clear(), которая будет брать переменную $db из глобальной области видимости global $db ;
- пройдемся в цикле foreach по массиву $_POST и возьмем ключ (name , text ) и значение.
- затем в массив $_POST в соответствующий ключ $key подставим экранированное значение,
то есть, значение обработанное функцией mysqli_real_escape_string ().
- на первой итерации: $key -> ($_POST['name']) = "соответствующее значение" ,
- на второй итерации: $key -> ($_POST['text']) = "соответствующее значение" и т. д.
- в итоге у нас получиться массив $_POST , но уже с экранированными данными.

Тогда в функции save_mess () вместо строк $name = ... и $text = ...
1) - мы вызовем функцию clear(), которая экранирует все данные в массиве $_POST .
2) - и с помощью функции extract() получим необходимые нам переменные $name и $text ,
то есть, возьмем из массива $_POST соответствующие ключи (name , text) и создадим соответствующие им переменные ($name , $text).
(Функция extract - извлекает из массива элементы и создает для них соответствующие переменные.)


Файл funcs.php


-- файл funcs.php --

<?php
function clear(){
global $db ;
foreach ($_POST as $key => $value ){
$_POST[$key] = mysqli_real_escape_string($db, $value);
}
}

// изменяем функцию save_mess
function save_mess(){
global $db ;
// вызываем функцию clear, которая экранирует все данные в массиве $_POST
clear();
// получаем переменные $name и $text
extract($_POST);

//$name = mysqli_real_escape_string($db, $_POST['name']);
//$text = mysqli_real_escape_string($db, $_POST['text']);

// составляем запрос
$query = "INSERT INTO gb (name, text) VALUES ('$name', '$text')";

// выполняем запрос (без проверки)
mysqli_query($db, $query);
}
?>



Проверим. Введем в поля данные:


guest3



Жмем "написать", проверяем таблицу gb:


guest4



- в таблице появилась новая запись. Это значит, что функция clear() работает.



Считывание и вывод данных




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


Файл index.php


-- файл index.php --

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

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

// принятие данных из формы
// если у нас не пуст массив $_POST, то вызовем некую функцию: save_mess
if (! empty ($_POST )){
save_mess();
// производим редирект
header("Location: {$_SERVER['PHP_SELF']}");
exit ;
}

$messages = get_mess();
print_arr($messages);

?>


<!doctype html>
<html Lang="en">
...
...
...
</html>




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


-- файл funcs.php --

<?php
function clear(){
global $db ;
foreach ($_POST as $key => $value){
$_POST[$key] = mysqli_real_escape_string($db, $value);
}
}

function save_mess(){
global $db ;
// вызываем функцию clear(которая экранирует все данные в массиве $_POST)
clear();
// получаем переменные $name и $text
extract($_POST);

//$name = mysqli_real_escape_string($db, $_POST['name']);
//$text = mysqli_real_escape_string($db, $_POST['text']);

// составляем запрос
$query = "INSERT INTO gb (name, text) VALUES ('$name', '$text')";

// выполняем запрос (без проверки)
mysqli_query($db, $query);
}

// Пользовательская функция get_mess
function get_mess(){
// соединение с базой данных
global $db ;
// запрос на выборку
$query = "SELECT * FROM gb ORDER BY id DESC" ;
// выполняем запрос
$res = mysqli_query($db, $query );
// возвращаем готовый ассоциативный массив
return mysqli_fetch_all($res, MYSQLI_ASSOC );
}

// функция для распечатки массива
function print_arr($arr){
echo'<pre>' . print_r($arr, true) . '</pre>';
}
?>



- в переменную $messages попадает нужный нам массив get_mess(); и мы можем его распечатать - print_arr($messages).


Получим в браузере:


Array
(
[0] => Array
(
[id] => 7
[name] => хакер
[text] => Это строка (') с
апострофом
[date] => 2019-05-30 22:12:42
) [1] => Array
(
[id] => 6
[name] => Саша
[text] => Привет!
Это строка (') с апострофом
[date] => 2019-05-29 22:49:44
)
[2] => Array
(
[id] => 5
[name] => d'Artanian
[text] => Имя с апострофом
[date] => 2019-05-26 21:46:53
)
[3] => Array
(
[id] => 4
[name] => Ваня
[text] => Hello!
[date] => 2019-05-21 22:26:04
)
[4] => Array
(
[id] => 3
[name] => Петя
[text] => )))))!
[date] => 2019-05-21 22:03:41
)
[5] => Array
(
[id] => 2
[name] => Вася
[text] => Привет!
Это второе сообщение!!
[date] => 2019-05-21 21:52:24
)
[6] => Array
(
[id] => 1
[name] => Андрей
[text] => Привет!
Это первое сообщение!
[date] => 2019-05-21 21:51:39
)
)




Проходимся по массиву и выводим его на экран.


Файл index.php


-- файл index.php --

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

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

// принятие данных из формы
// если у нас не пуст массив $_POST, то вызовем некую функцию: save_mess
if (! empty ($_POST )){
save_mess();
// производим редирект
header("Location: {$_SERVER ['PHP_SELF']}");
exit ;
}

$messages = get_mess();
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 ) : ?>
<!-- выводим полученные наши данные -->
<div class= "messages">
<hr>
<p>
Автор: <?= $message['name'] ?> | Дата: <?= $message['date'] ?>
</p>
<div <?= nl2br(htmlspecialchars ($message['text'])) ?> </div>
<hr>
</div>
<?php endforeach; ?>
<?php endif ?>
</body>
</html>




После обновления страницы, получим:


guest5



- появились посты из таблицы базы данных


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


php24.png






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