PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи

Страниц (1): [1]

> Найдено сообщений: 6
Vechnost Отправлено: 13 Ноября, 2014 - 03:14:51 • Тема: Как работает перезапрос страницы? • Форум: Вопросы новичков

Ответов: 2
Просмотров: 976
Смотрю курсы УЦ "Специалист". Там рассказывается такой рецепт.

Для формы по умолчанию (если не указан) используется метод 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();

Обрывающий перезапрос - сразу после действий по обработке данных. Разве может информация отправиться хоть раз?
Vechnost Отправлено: 08 Сентября, 2014 - 20:40:47 • Тема: Обновление id, не имеющих auto increment • Форум: Вопросы новичков

Ответов: 6
Просмотров: 234
Конечно, AI уникален - кто ж спорит. Вероятно, этим вы хотите сказать, что отказываться от AI не имеет смысла, не так ли?

То есть, идея самому контролировать заполнение id - изначально тухлая затея?
Vechnost Отправлено: 08 Сентября, 2014 - 16:35:26 • Тема: Обновление id, не имеющих auto increment • Форум: Вопросы новичков

Ответов: 6
Просмотров: 234
А что, проблемы нету?!!

Ну, то есть да - то, что чём я говорю вначале, это скорее не проблема, а нюанс. Просто мне кажется, что id необходимо отслеживать без auto increment. Не логично как-то, когда удалишь с сайта старые записи, а потом отсчёт начинается с какой-нибудь там 369-й записи... Ведь именно так будет с ai.

Мой алгоритм предполагает уменьшение всех id, стоящих после удалённого. Если записей действительно много - мне кажется, нагрузка будет большая.

Ну подумайте: берётся id, который мы удалили. Следом за ним - id большего размера, и мы его уменьшаем. Следом следом - ещё id, и его уменьшаем... Чтобы выстроить ровную цепочку: 1,2,3,4,5,6,7,8 вместо разорванной 1,2,3,4,6,7,8. Ели записей 8 или 10, то цикл будет посылать 8 или 10 запросов на переписывание следующих id. Если записей (этих самых id) ОЧЕНЬ много (сайт разросся на годы), то и запросов будет столько же, сколько стоит записей после удалённой нами. И если их 1000, то, удалив 995-ю запись, мы получим всего 5 запросов, НО если мы удалим 5-ю или 1-ю запись - посчитайте сами, сколько будет запросов.

А если стану удалять запись в тот момент, когда на сайте несколько сотен (или тысяч) посетителей??? (ну, хороший сайт, раскрученный)

Неужели для современных серверов это настолько незначительно?

Или вы хотите сказать, что вообще не стоит заниматься этим? Либо с AI, либо никак?
Vechnost Отправлено: 08 Сентября, 2014 - 16:13:04 • Тема: Обновление id, не имеющих auto increment • Форум: Вопросы новичков

Ответов: 6
Просмотров: 234
Здравствуйте.

Есть таблица с записями, у каждого - свой id. Если у этих id стоит A_I, то возникает такая проблема: если удалить, скажем, 5 запись из 10, то 5 записи уже не будет никогда (при создании новой записи следующий id будет 11). Для порядка, имхо, неплохо бы не использовать A_I и написать скрипт, отслеживающий и обновляющий id.

Алгоритм я себе представляю примерно таким (псевдокод):

1. Добавление новой записи

В цикле

SELECT id FROM таблица

и заносим в $id_array;

$index = count($id_array);
$new_id = $id_array[$index]++;

INSERT INTO таблица (id) VALUES ($new_id);

Тут могут быть неточности с точки зрения php, не обращайте внимания - я код не продумывал, просто привожу для описания общей сути.

Новая запись имеет id на 1 больше, чем последний id в таблице. Всё хорошо. Но вот с удалением...

2. Удаление записи

В форме удаления выбираем запись, то есть id (это переменная $id);

DELETE FROM таблица WHERE id=$id;

Если удалена запись номер 5, то следом за 4 будет 6. Чтобы этого не было,

В цикле проделываем
$new_id = $id++;
UPDATE таблица SET id=$id WHERE id=$new_id;
До тех пор, пока в таблице есть ещё записи

Образовавшийся пропуск в ряде величин заполняется путём уменьшения всех id, стоящих после того, который мы удалили.

СУТЬ ВОПРОСА.

Если в таблице 10 или 20 записей - ещё ничего, но что если в блоге за несколько лет накопилась 1000 записей? Тогда, при попытке удалить 5-ю запись, запрос UPDATE будет посылаться 994 раза! Как сервер воспримет такую нагрузку?

В общем, коряво как-то выходит. Хочу спросить - есть ли какое-то более аккуратное решение?

P.S. Я слышал, что в sql-сервере предусмотрены какие-то процедуры, циклы... Может быть, не париться о php-шном "обновляторе", а сразу MySQL учить и в этом направлении курс держать?
Vechnost Отправлено: 31 Августа, 2014 - 15:27:19 • Тема: Помогите с циклом • Форум: Вопросы новичков

Ответов: 2
Просмотров: 126
СПАСИБО!!!! Заработало. Всё-таки я это упустил... Глаза замыливаются, когда долго на код смотришь.
Vechnost Отправлено: 31 Августа, 2014 - 15:16:56 • Тема: Помогите с циклом • Форум: Вопросы новичков

Ответов: 2
Просмотров: 126
Всем привет.

Смотрю видеокурсы УЦ "Специалист" - хорошие курсы, серьёзные. Но вот на последнем уроке 2 уровня без видимых причин затык случился.

Ребят, помогите! Я уже всю голову сломал!

Ксати, у них Apache, PHP и MySql отдельну ставилисть, а у меня - денвер.

Итак, суть проблемы.

Строим книжный магазин. Есть БД под именем eshop а в ней (в числе прочих) - таблица catalog с полями author, title, pubyear и price. В ней - несколько записей. Есть файл catalog.php, который всю эту прелесть выводит. Вот он:

CODE (htmlphp):
скопировать код в буфер обмена
  1.  
  2. <?php
  3.         // запуск сессии
  4.         session_start();
  5.         // подключение библиотек
  6.         require "eshop_db.inc.php";
  7.         require "eshop_lib.inc.php";
  8. ?>
  9. <html>
  10. <head>
  11.         <title>Каталог товаров</title>
  12. </head>
  13. <body>
  14. <p>Товаров в <a href='basket.php'>корзине:</a> <?=$count?></p>
  15. <?php
  16.  
  17. ?>
  18. <table border="1" cellpadding="5" cellspacing="0" width="100%">
  19. <tr>
  20.         <th>Автор</th>
  21.         <th>Название</th>
  22.         <th>Год издания</th>
  23.         <th>Цена, руб.</th>
  24.         <th>В корзину</th>
  25. </tr>
  26. <?php
  27.         $goods = select_all();
  28.         foreach($goods as $item){
  29. ?>
  30.                 <tr>
  31.                         <td><?=$item["author"]?></td>
  32.                         <td><?=$item["title"]?></td>
  33.                         <td><?=$item["pubyear"]?></td>
  34.                         <td><?=$item["price"]?></td>
  35.                         <td><a href='add2basket.php?id=<?=$item["id"]?>'>в корзину</a></td>
  36.                 </tr>
  37. <?php  
  38.         }
  39. ?>
  40. </table>
  41. </body>
  42. </html>
  43.  

Вверху подключается библиотека, вот её функции, которые вызвыаются в этом файле:


PHP:
скопировать код в буфер обмена
  1. // конвертируем данные из базы в массив
  2. function db2array($data){
  3.         $arr = array();
  4.         while ($row = mysql_fetch_assoc($data)){
  5.                 $arr[] = $row;
  6.                 return $arr;
  7.         }
  8. }
  9.  
  10. // возвращает все содержимое каталога товаров
  11. function select_all(){
  12.         $sql = "SELECT * FROM catalog";
  13.         $result = mysql_query($sql) or die(mysql_error());
  14.         return db2array($result);
  15. }
  16.  

Вроде бы всё понятно, только выдодится лишь ОДНА запись, а их в БД несколько. Чтобы понять, в чём тут подвох,я в файле catalog.php после $goods = select_all() псиал print_r($goods); exit; и понял, что ошибка происходит в функции db2array() на уровне цикла while - он почему-то срабатывает однократно.

Самое интересное, что у препода на видео всё работает! Я этот код буквально с экрана списывал. Думаю-думаю - и понять ничего не могу. Ну какие у него могут быть причины работать не правильно?! Код-то вроде хороший, все должно быть ОК

Страниц (1): [1]
Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB