@Pavl-85

Как в php-коде сделать, чтобы данные после определённых действий на странице браузера не оставались в кэше браузера?

При изучении php-кода столкнулся со следующей проблемой. В коде в файле catalog.php есть строка:

<td> <a href="add2basket.php?id=<?= $item['id']?>">В корзину</a></td>

и, когда на странице нажимаешь ссылку "В корзину", то в следующей строке:

<p>Товаров в <a href="basket.php">корзине</a>: <?= $count?></p>

вместо $count появляется количество товаров в корзине. Проблема в том, что, когда повторно нажимаешь "В корзину" напротив того же товара, то $count не меняется. Удаление куки в браузере и удаление товара из корзины не меняет ситуацию. А вот, если удалить кэш в браузере, то $count (кол-во товаров в корзине снова меняется). Исходя из этого я сделал вывод, что проблема с кешем в браузере. То есть, насколько понимаю, нужно сделать так, чтобы при нажатии "В корзину" не происходило сохранении в кэше браузера. Попробовал, применить способ для очистки кэша. Строка стала иметь вид:
<td><form method="get" autocomplete="off"><a href="add2basket.php?id=<?= $item['id']?>">В корзину</a></form></td>

но не получилось.
Можно ли методом get, как-то решить такую проблему?
Полный код файла catalog.php:
<?php // подключение библиотек
require "inc/lib.inc.php";
require "inc/config.inc.php";
?>
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Каталог товаров</title>
</head>
<body>
<p>Товаров в <a href="basket.php">корзине</a>: <?= $count?></p>

<table border="1" cellpadding="5" cellspacing="0" width="100%">
    <tr>
        <th>Название</th>
        <th>Автор</th>
        <th>Год издания</th>
        <th>Цена, руб.</th>
        <th>В корзину</th>
    </tr>
    <?php
    $goods = selectAllItems();
    foreach($goods as $item):
        ?>
        <tr>
            <td><?= $item['title']?></td>
            <td><?= $item['author']?></td>
            <td><?= $item['pub']?></td>
            <td><?= (int)$item['price']?></td>
            <td> <a href="add2basket.php?id=<?= $item['id']?>">В корзину</a></td>
        </tr>
    <? endforeach; ?>
</table>
</body>
</html>

Код файла basket.php:
<?php
// подключение библиотек
require "inc/lib.inc.php";
require "inc/config.inc.php";
?>
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Корзина пользователя</title>
</head>
<body>
<h1>Ваша корзина</h1>
<?php
$goods = myBasket();
$sum = 0;
if (!$count) {
    echo "<p>Товаров нет. Вернитесь в <a href='catalog.php'>каталог</a></p>";
    exit;
} else {
    echo "<p> Вернуться в <a href='catalog.php'>каталог</a> </p>";
}
?>
<table border="1" cellpadding="5" cellspacing="0" width="100%">
    <tr>
        <th>N п/п</th>
        <th>Название</th>
        <th>Автор</th>
        <th>Год издания</th>
        <th>Цена, руб.</th>
        <th>Количество</th>
        <th>Удалить</th>
    </tr>
    <?php
    $i = 1; $sum = 0;
    foreach($goods as $item): ?>
        <tr>
            <td><?= $i?></td>
            <td><?= $item['title']?></td>
            <td><?= $item['author']?></td>
            <td><?= $item['pub']?></td>
            <td><?= (int)$item['price']?></td>
            <td><?= $item['quantity']?></td>
            <td><a href="delete_from_basket.php?id=<?= $item['id']?>">Удалить</a></td>
        </tr>
        <?
            $i++;
            $sum += $item['price'] * $item['quantity'];
    endforeach;
    ?>
</table>
<p>Всего товаров в корзине на сумму: <?= $sum ?> руб.</p>
<div align="center">
    <input type="button" value="Оформить заказ!" onClick="location.href='orderform.php'" />
</div>
</body>
</html>

Код файла add2basket.php:
<?php
require "inc/lib.inc.php";
require "inc/config.inc.php";

add2Basket($_GET['id']);
header("Location: http://mysite.local/eshop/catalog.php", true, 301);
exit;

Также код со всеми функциями lib.inc.php:
<?php

function clearInt($data){
    return abs((int)$data);
}

function clearStr($data){
    global $link;
    return mysqli_real_escape_string($link, trim(strip_tags($data)));
}

function addItemToCatalog ($title, $author, $pub, $price) { // сохраняет новый товар в таблицу catalog и принимающую в виде аргументов название, автора, год издания и цену товара
    global $link;
    $sql = 'INSERT INTO catalog (title, author, pub, price) VALUES (?, ?, ?, ?)';
    if (!$stmt = mysqli_prepare($link, $sql)) { // Подготавливает SQL-запрос и возвращает указатель на это выражение, который может использоваться для дальнейших операций с этим выражением. Запрос должен состоять из одного SQL выражения.
        return false;
    } else {
        mysqli_stmt_bind_param($stmt, "ssii", $title, $author, $pub, $price); // Привязывает переменные к меткам параметров в SQL-выражении, которое было подготовлено фукнцией mysqli_prepare().
        mysqli_stmt_execute($stmt); // Выполняет запрос, который был ранее подготовлен функцией mysqli_prepare(). Если в запросе есть метки параметров, они будут заменены привязанными к ним значениями.
        mysqli_stmt_close($stmt); // Закрывает подготовленный запрос. mysqli_stmt_close() также освобождает дескриптор запроса. Если по текущему запросу получен результат, то эта функция очищает его для того, чтобы мог быть выполнен следующий запрос.
        return true;
    }
}

function selectAllItems() { // возвращает все содержимое каталога товаров в виде ассоциативного массива
    global $link;
    $sql = 'SELECT id, title, author, pub, price FROM catalog';
    if (!$result = mysqli_query($link, $sql)) { // Выполняет запрос query к базе данных.
        return false;
    } else {
        $items = mysqli_fetch_all($result, MYSQLI_ASSOC); // извлекает все строки из результирующего набора и помещает их в ассоциативный массив
        mysqli_free_result($result); // Освобождает память, занятую результатами запроса.
        return $items;
    }
}

function saveBasket() { // сохраняет корзину с товарами в куки
    global $basket;
    $basket = base64_encode(serialize($basket));  //serialize() - генерирует пригодное для хранения представление переменной.
    // Это полезно для хранения или передачи значений PHP между скриптами без потери их типа и структуры.
    // base64_encode() -- кодирует в base64. Эта кодировка предназначена для корректной передачи бинарных данных по протоколам,
    // не поддерживающим 8-битную передачу, например, для отправки тела письма.
    setcookie('basket', $basket, 0x7FFFFFFF); // setcookie() задает cookie, которое будет передано клиенту вместе с другими HTTP-заголовками.
}

function basketInit() { // создает, либо загружает в переменную $basket корзину с товарами, либо создает новую корзину с идентификатором заказа
    global $basket, $count;
    if (!isset($_COOKIE['basket'])) {  // определяет, была ли установлена переменная значением отличным от NULL
        $basket = ['orderid' => uniqid()]; // uniqid — сгенерировать уникальный ID
        saveBasket();
    } else {
        $basket = unserialize(base64_decode($_COOKIE['basket']));
        $count = count($basket) - 1;
    }
}

function add2Basket($id) { // добавляет товар в корзину пользователя и принимает к качестве аргумента идентификатор товара
    global $basket;
    $basket[$id] = 1;
    saveBasket();
}

function myBasket() { //возвращает всю пользовательскую корзину в виде ассоциативного массива
    global $link, $basket;
    $goods = array_keys($basket); //возвращает все или некоторое подмножество ключей массива
    array_shift($goods); // извлекает первый элемент массива
    if (!$goods) {
        return false;
    };
    $ids = implode(",", $goods); // объединяет элементы массива в строку
    $sql = "SELECT id, author, title, pub, price FROM catalog WHERE id IN ($ids)";
    if (!$result = mysqli_query($link, $sql)) {
        return false;
    };
    $items = result2Array($result);
    mysqli_free_result($result); //освобождает память, занятую результатами запроса.
    return $items;
}

function result2Array($data) { //принимает результат выполнения функции myBasket и возвращает ассоциативный массив товаров, дополненный их количеством
    global $basket;
    $arr = [];
    while($row = mysqli_fetch_assoc($data)) { //извлекает результирующий ряд в виде ассоциативного массива
        $row['quantity'] = $basket[$row['id']];
        $arr[] = $row;
    };
    return $arr;
}


function deleteItemFromBasket($id) { // удаляет товар из корзины, принимая в качестве аргумента его идентификатор
    global $basket;
    unset($basket[$id]); // удаляет элемент из массива
    saveBasket();
}

function saveOrder($datetime){
    global $link, $basket; $goods = myBasket();
    $stmt = mysqli_stmt_init($link); $sql = 'INSERT INTO orders ( title, author, pub, price, quantity, orderid, datetime) VALUES (?, ?, ?, ?, ?, ?, ?)';
    if (!mysqli_stmt_prepare($stmt, $sql)) return false;
    foreach($goods as $item){ mysqli_stmt_bind_param($stmt, "ssiiisi", $item['title'], $item['author'], $item['pub'], $item['price'], $item['quantity'], $basket['orderid'], $datetime);
        mysqli_stmt_execute($stmt);
    }
    mysqli_stmt_close($stmt);
    setcookie("basket", "", 1);
    return true;
}


Заранее, спасибо!
  • Вопрос задан
  • 128 просмотров
Пригласить эксперта
Ответы на вопрос 1
@galaxy
Ну да, конечно же, виновато кеширование, тупой php, инопланетяне.
Почитай свой код (если он свой) и попробуй найти, где у тебя вообще меняется переменная $count и какая цепочка вызовов к этому приводит. И заодно подумай, что происходит при повторном добавлении одного и того же товара.

spoiler
С кеширование, впрочем, тоже могут быть проблемы, ибо так делать не стоит:
header("Location: http://mysite.local/eshop/catalog.php", true, 301);

Редирект перманентный и браузер его пропустить
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
от 150 000 до 250 000 ₽
от 210 000 до 250 000 ₽
Depcon Екатеринбург
от 100 000 до 170 000 ₽
22 окт. 2021, в 06:36
110000 руб./за проект
22 окт. 2021, в 06:33
6000 руб./за проект
22 окт. 2021, в 06:26
500 руб./за проект