Смотрю курсы УЦ "Специалист". Там рассказывается такой рецепт.
Для формы по умолчанию (если не указан) используется метод GET. Обновление страницы по f5 - это повтор предыдущего запроса. Если кто-то ввёл данные в форму, а потом обновил страницу по f5, то ещё одна копия записи будет занесена в базу. Дабы избежать этого, можно использовать перезапрос страницы методом GET.
Дело в том, что все страницы по умолчанию загружаются методом GET. Если на странице есть форма с методом POST, то при нажатии enter она летит, само собой, post'ом. Пишем:
<?
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$name = strip_tags($_POST["name"]);
$age = $_POST["age"] * 1;
// Сохранение в cookie на сутки
setcookie("userName", $name, time() + 24*60*60);
setcookie("userAge", $age, time() + 24*60*60);
header("Location: ".$SERVER["PHP_SELF"]);
}
else {
// Чтение куки
$name = strip_tags($_COOKIE["userName"]);
$age = $_COOKIE["userAge"] * 1;
}
?>
Когда мы в следующий раз обновляем страницу, форма посылается вновь, НО браузер натыкается на
header("Location: ".$SERVER["PHP_SELF"]);
Фича в том, что header("Location: ".$SERVER["PHP_SELF"]) запрашивает страницу методом GET.
Итак, браузер принимает ответ на post-запрос, НО после get-перезапроса предыдущий post-запрос обрывает и просит get-ответ. А поскольку этот запрос GET, а не POST, запись не отправляется и дублирования коммента (статьи, и т.п.) не происходит.
Вот весь скрипт:
-------------------------------- -
<?
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$name = strip_tags($_POST["name"]);
$age = $_POST["age"] * 1;
// Сохранение в cookie на сутки
setcookie("userName", $name, time() + 24*60*60);
setcookie("userAge", $age, time() + 24*60*60);
header("Location: ".$SERVER["PHP_SELF"]);
exit();
}
else {
// Чтение куки
$name = strip_tags($_COOKIE["userName"]);
$age = $_COOKIE["userAge"] * 1;
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Сохранение состояния формы</title>
</head>
<body>
<h1>Сохранение состояния формы</h1>
<form action="<?=$_SERVER["PHP_SELF"]?>" method="post">
Ваше имя:
<input type="text" name="name" value="<?=$name?>"><br>
Ваш возраст:
<input type="text" name="age" value="<?=$age?>"><br>
<input type="submit" value="Передать">
</form>
<?
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if ($name and $age) {
echo "<h1>Привет, $name</h1>";
echo "<h3>Тебе $age лет</h3>";
}
else {
print "<h3>Заполните все поля!</h3>";
}
}
?>
</body>
</html>
--------------------------
Я так понимаю, что, по логике препода, после первой отправки формы всё должно заноситься куки и отображаться:
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if ($name and $age) {
echo "<h1>Привет, $name</h1>";
echo "<h3>Тебе $age лет</h3>";
}
else {
print "<h3>Заполните все поля!</h3>";
}
}
а после попытки обновить по f5 не должна отображаться даже форма (exit блокирует её прорисовку):
header("Location: ".$SERVER["PHP_SELF"]);
exit();
Но ведь здравый смысл подсказывает, что данные не должны отправляться даже в первый раз! собственно, в моём файле так и происходит.
get-перезапрос обрывает post-запросы, при этом первый post-запрос почему-то обрываться не должен. Ребят, ну почему данные в первый-то раз отправляются??? Ведь не должны! и в моём скрипте не отправляются! Почему это у бауманского препода работает??!!! Почему это вообще должно работать? Разве header("Location: ".$SERVER["PHP_SELF"]) не должно вообще препятствовать отправке post-запроса?
Вот не могу понять, хоть тресни. Несколько раз этот фрагмент видео пересмотрел - не понял. Эта информация не даёт мне покоя. Может, растолкуете?
Ещё раз:
$name = strip_tags($_POST["name"]);
$age = $_POST["age"] * 1;
setcookie("userName", $name, time() + 24*60*60);
setcookie("userAge", $age, time() + 24*60*60);
header("Location: ".$SERVER["PHP_SELF"]);
exit();
Обрывающий перезапрос - сразу после действий по обработке данных. Разве может информация отправиться хоть раз?
|