Друзья, всем привет! Я новичок в сфере php. Чтобы было понятно, что я делаю, опишу в кратце: Хочу создать табличку, куда буду добавлять какие-то карточки товаров, изменять их и удалять. Если с добавлением все было хорошо, то вот после добавления функции удаления - все пошло наперекосяк. Вся информация сохраняется в файл JSON в объекты. Проблемы: 1. При обновлении страницы добавляется пустое значение в файл 2. При удалении удаляется только значения массива, сам же он остается с пустыми значениями в файле json, тоесть остаются пустые строки, с порядковым номером, но без информации + добавляется пустой объект. 3. И самый непонятный баг - после удаления хоть одного объекта - при добавлении- добавляется пустое значение, и только во второй раз добавляется значение, но с предыдущими данными, как будто они закешировались, или сервер не успел вернуть обновленный файл. А хотелось бы, чтобы: 1. При перезагрузке страницы ничего лишнего не сохранялось в файл 2. Удалялся только тот объект, на который я нажму и все номера (порядковые) перестраивались на место удаленного объекта. 3. Не было этого непонятного бага. Помогите разобраться, пожалуйста! Уже неделю голову ломаю, пол ютуба и интернета перерыл, не знаю, что делать. Вот код php PHP: <?php $name = htmlspecialchars($_POST['name']); $name = trim($name); $info = htmlspecialchars($_POST['info']); $info = trim($info); $oprice = htmlspecialchars($_POST['oprice']); $oprice = trim($oprice); $price = htmlspecialchars($_POST['price']); $price = trim($price); $idcrm = htmlspecialchars($_POST['idcrm']); $idcrm = trim($idcrm); //Если файл существует - получаем его содержимое $additionalArray = array( 'name' => $name, 'info' => $info, 'oprice' => $oprice, 'price' => $price, 'idcrm' => $idcrm ); //open or read json data $data_results = file_get_contents('file.json'); $tempArray = json_decode($data_results, true); //append additional json to json file $tempArray[] = $additionalArray ; $jsonData = json_encode($tempArray); $result = file_put_contents('file.json', $jsonData); $odel = @$_POST['delname']; if (isset($_POST['del'])){ unset($tempArray[$odel]); file_put_contents('file.json', json_encode($tempArray, JSON_FORCE_OBJECT | JSON_NUMERIC_CHECK)); header('Location: '. $_SERVER['HTTP_REFERER']); } ?> Вот html HTML: <table class="table table-border"> <thead class="table-dark"> <tr> <th scope="col" style="width: 5%;">№</th> <th scope="col" style="width: 15%;" >Название</th> <th scope="col" >Описание</th> <th scope="col" style="width: 15%;" >Цена old</th> <th scope="col" style="width: 15%;" >Цена new</th> <th scope="col" style="width: 5%;" >idCrm</th> <th scope="col" style="width: 10%;">Действие</th> </tr> </thead> <tbody> <?php for($i = 0; $i < count($tempArray); ++$i) { ?> <tr> <th scope="row"><?php echo $i + 1 ;?></th> <td><?php echo $tempArray[$i][name] ?></td> <td><?php echo $tempArray[$i][info] ?></td> <td><?php echo $tempArray[$i][oprice] ?></td> <td><?php echo $tempArray[$i][price] ?></td> <td><?php echo $tempArray[$i][idcrm] ?></td> <td> <button class="btn btn-success mb-3 mp-3" type="button" data-bs-toggle="modal" data-bs-target="#exampleModal"><i class="bi bi-pencil-square"></i></button> <button class="btn btn-danger mb-3 mp-3" type="button" data-bs-toggle="modal" data-bs-target="#del<?php echo $i;?>"><i class="bi bi-trash"></i></button> <!-- Удаление --> <div class="modal fade " id="del<?php echo $i;?>" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true"> <div class="modal-dialog " style="max-width: 750px;"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="exampleModalLabel">Удалить: <?php echo $tempArray[$i][name];?> ?</h5> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <div class="modal-body"> <form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method="post"> <div class="input-group"> <input type="hidden" name="delname" value="<?php echo $i; ?>"> </div> <button class="btn btn-danger del" name="del">Удалить</button> </div> <?php ?> </form> </div> </div> </div> </div> </td> </tr> <?php } ?> </table> Вот я выгрузил на хостинг свою рукоблудие, дабы можно было воочию увидеть все баги =)) https://katalog.kupi-vip.space/proba/index.php Вот технический файл, где можно глянуть массивы декодированные из файла json, может кому-то нужно будет. https://katalog.kupi-vip.space/proba/arr.php
1. Пост-запросы лучше обрабатывать отдельными файлами (если не используется единая точка входа/фреймворк), после обработки делать редирект куда-нибудь ещё (как раз вашу проблему решает). 2. Ну так у вас вся логика вместе, поставьте хоть иф какой-нибудь, чтоб проверял, что мы сейчас делаем, добавляем или удаляем 3. Ну и да, база на json-файлах, это такое себе. Лучше взять нормальную СУБД, где ооооочень умные дяди уже позаботились о таких вещах, как обработка одновременных запросов и т.п. --- Добавлено --- При использовании фреймворка/единой точки входа post и get тоже обрабатываются отдельно, но там обработчики могут находиться и в одном файле
Благодарю за рекомендацию! Тоже так думаю. Вынесу обработчики в отдельные файлы. Теперь стоит вопрос, чтобы при удалении данных из json, удалялись не только значения массива, но и сам ключ объекта. И чтобы нумерация смещалась не оставляя пропусков. Если это возможно - дайте рекомендации.
Это ж надо блок на GET-запрос ставить (понятно, что можно обойтись обязательными для самого POST'а проверками, но все равно придется каждый раз об этом задумываться), выдумывать разные имена файлов. Проще вилку вставить POST/не POST. Плюс при обработке связанных GET/POST часто бывает общий начальный код. --- Добавлено --- Не всегда. Есть общий обработчик, даже когда можно делать частные по методу запроса. --- Добавлено --- Это хрень. Сразу видно, что вы с норм. БД не работали. Оставьте только идентификацию. Нумерацией пусть вьюшки занимаются. --- Добавлено --- Если бы удаляли по «плавающему» номеру, а не по id-шнику, у всех бы все шло наперекосяк
Я учел советы и принял решение отказаться от JSON файла. Буду загонять данные в базу MySQL. В принципе это решит проблему с выводом и вторую проблему с безопасностью. Но столкнулся сразу же с проблемой - не могу подключиться к базе данных с помощью PDO. Хотя пользователь имеет доступ и раз 20 все перепроверил. Ошибка есть и не пропускает. Ошибка: SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost' (using password: YES) Подскажите решение данной проблемы. П.с. Установка пароля ничего не дает, всего лишь No меняется на YES. PHP: $host = 'localhost'; $db = 'goods'; $user = 'root'; $pass = 'root'; try { $pdo = new PDO("mysql:host=$host; dbname=$db", $user, $pass); } catch (PDOException $e) { die("Ошибка: " .$e->getMessage()); }
Наверное, лучше создать отдельную тему. У root-а точно пароль root? И возьмите за правило вместе с БД сразу создавать (одноименного) пользователя, из-под которого и работать с этой БД (у пользователя права только на работу с этой БД; можно даже их ограничивать).
В общем проблема сама собой решилась. После 100500 перезагрузок mysql и 100500 изменений пользователей, ошибка исчезла. Что там конкретно было не так - уже сложно сказать, но вроде пока работает --- Добавлено --- Каких я пользователей не назначал - не работало. Начало работать, когда назначил того, под которым зашел в бд, хотя его не правил. В общем я не понимаю, почему не работало с другими пользователями.
Из-под рута создаете БД и одноименного пользователя с правами для работы с этой БД. Потом работаете с БД из-под соотв. пользователя.