P
P
Pavl-852021-09-03 20:43:06
PHP
Pavl-85, 2021-09-03 20:43:06

How to make in php code so that the data after certain actions on the browser page does not remain in the browser cache?

When studying php-code, I encountered the following problem. In the code in the catalog.php file, there is a line:

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

and when you click on the "Add to Cart" link on the page, then in the following line:

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

$count is replaced by the number of items in the cart. The problem is that when you click "Add to cart" again next to the same product, $count does not change. Deleting cookies in the browser and deleting the product from the cart does not change the situation. But if you delete the cache in the browser, then $count (the number of items in the cart changes again). Based on this, I concluded that the problem is with the cache in the browser. That is, as far as I understand, you need to make sure that when you click "Add to cart", it does not save in the browser cache. I tried to apply the method to clear the cache. The line began to look like:
<td><form method="get" autocomplete="off"><a href="add2basket.php?id=<?= $item['id']?>">В корзину</a></form></td>

but it didn't work.
Can the get method somehow solve this problem?
Full code of the catalog.php file :
<?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 file code :
<?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 file code :
<?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;

Also code with all lib.inc.php functions :
<?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;
}


Thanks in advance!

Answer the question

In order to leave comments, you need to log in

1 answer(s)
G
galaxy, 2021-09-03
@galaxy

Well, yes, of course, caching, stupid php, aliens are to blame.
Read your code (if it's yours) and try to find where your $count variable changes at all and what chain of calls leads to this. And at the same time, think about what happens when you add the same product again.

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

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

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question