PHP
Практика создания гостевой книги с использованием БД
2 Принятие данных из формы и реализация сохранения сообщений .
Функция для экранирования данных.
Переделаем гостевую книгу, которая работает на файлах (из раздела "Практика создания гостевой книги") под работу с базой данных.
База данных у нас есть - gb, таблица с сообщениями в ней есть - таблица gb
Нам необходимо реализовать добавление и сохранение записей в эту таблицу, и вывод записей этих сообщений из этой таблицы.
Файл index.php с формой для добавления сообщениий.
-- файл index.php --
<?php
("Content-type: text/html; charset=utf-8 ");
(-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 = @ ( 'localhost' , 'root' , '', 'gb' ) or die ( 'Ошибка соединения с БД');
if (! $db ) die ( ());
// Установка кодировки соединения
( $db, "utf8" ) or die ( 'Не установлена кодировка' );
?>
Файл index.php
-- файл index.php --
<?php
("Content-type: text/html; charset=utf-8 ");
(-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 (){
// переменная $db (индификатор соединения),
// взятая из глобальной области видимости (global)
global $db ;
// переменные $name, $text берем из массива $_POST и экранируем их
// функцией mysqli_real_escape_string
$name = ($db, $_POST['name']);
$text = ($db, $_POST['text']);
// составляем запрос
$query = "INSERT INTO gb (name, text) VALUES ('$name', '$text')";
// выполняем запрос (без проверки)
($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
("Content-type: text/html; charset=utf-8 ");
(-1);
require_once 'connect.php' ; // подключаем файл connect.php
require_once 'funcs.php' ; // подключаем файл funcs.php
// принятие данных из формы
// если у нас не пуст массив $_POST, то вызовем некую функцию: save_mess
if (! empty ($_POST )){
();
// производим редирект
("Location: {$_SERVER['PHP_SELF']}");
exit ;
}
?>
<!doctype html>
<html Lang="en">
...
...
...
</html>
Введем в поля данные:
Жмем "написать", проверяем таблицу gb - в таблице появилась новая запись.
Функция для экранирования данных
Если данных много, можно написать функцию для их экранирования. Например:
Создадим функцию 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 (){
global $db ;
foreach ($_POST as $key => $value ){
$_POST[$key] = ($db, $value);
}
}
// изменяем функцию save_mess
function (){
global $db ;
// вызываем функцию clear, которая экранирует все данные в массиве $_POST
();
// получаем переменные $name и $text
($_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')";
// выполняем запрос (без проверки)
($db, $query);
}
?>
Проверим. Введем в поля данные:
Жмем "написать", проверяем таблицу gb:
- в таблице появилась новая запись. Это значит, что функция clear() работает.
Считывание и вывод данных
Для этого создадим в индексном файле переменную $messages в которую и будем считывать данные с помощью пользовательской функции get_mess ($messages = get_mess();)
Файл index.php
-- файл index.php --
<?php
("Content-type: text/html; charset=utf-8");
(-1);
require_once 'connect.php'; // подключаем файл connect.php
require_once 'funcs.php'; // подключаем файл funcs.php
// принятие данных из формы
// если у нас не пуст массив $_POST, то вызовем некую функцию: save_mess
if (! empty ($_POST )){
();
// производим редирект
("Location: {$_SERVER['PHP_SELF']}");
exit ;
}
$messages = ();
($messages);
?>
<!doctype html>
<html Lang="en">
...
...
...
</html>
Файл funcs.php - функция get_mess():
-- файл funcs.php --
<?php
function (){
global $db ;
foreach ($_POST as $key => $value){
$_POST[$key] = ($db, $value);
}
}
function (){
global $db ;
// вызываем функцию clear(которая экранирует все данные в массиве $_POST)
();
// получаем переменные $name и $text
($_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')";
// выполняем запрос (без проверки)
($db, $query);
}
// Пользовательская функция get_mess
function (){
// соединение с базой данных
global $db ;
// запрос на выборку
$query = "SELECT * FROM gb ORDER BY id DESC" ;
// выполняем запрос
$res = ($db, $query );
// возвращаем готовый ассоциативный массив
return ($res, MYSQLI_ASSOC );
}
// функция для распечатки массива
function ($arr){
echo'<pre>' . ($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
("Content-type: text/html; charset=utf-8");
(-1);
require_once 'connect.php' ; // подключаем файл connect.php
require_once 'funcs.php' ; // подключаем файл funcs.php
// принятие данных из формы
// если у нас не пуст массив $_POST, то вызовем некую функцию: save_mess
if (! empty ($_POST )){
();
// производим редирект
("Location: {$_SERVER ['PHP_SELF']}");
exit ;
}
$messages = ();
($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 <?= ($message['text'])) ?> </div>
<hr>
</div>
<?php endforeach; ?>
<?php endif ?>
</body>
</html>
После обновления страницы, получим:
- появились посты из таблицы базы данных
Структура файлов урока
Наверх Наверх