За последние 24 часа нас посетили 20996 программистов и 1136 роботов. Сейчас ищет 651 программист ...

Не работает удаление элемента массива и добавление.

Тема в разделе "PHP для новичков", создана пользователем Сергей Курц, 7 янв 2022.

  1. Сергей Курц

    Сергей Курц Новичок

    С нами с:
    7 янв 2022
    Сообщения:
    12
    Симпатии:
    0
    Друзья, всем привет!:)
    Я новичок в сфере php.
    Чтобы было понятно, что я делаю, опишу в кратце: Хочу создать табличку, куда буду добавлять какие-то карточки товаров, изменять их и удалять.

    Если с добавлением все было хорошо, то вот после добавления функции удаления - все пошло наперекосяк. Вся информация сохраняется в файл JSON в объекты.

    o_OПроблемы:
    1. При обновлении страницы добавляется пустое значение в файл
    2. При удалении удаляется только значения массива, сам же он остается с пустыми значениями в файле json, тоесть остаются пустые строки, с порядковым номером, но без информации + добавляется пустой объект.
    3. И самый непонятный баг - после удаления хоть одного объекта - при добавлении- добавляется пустое значение, и только во второй раз добавляется значение, но с предыдущими данными, как будто они закешировались, или сервер не успел вернуть обновленный файл.

    А хотелось бы, чтобы:
    1. При перезагрузке страницы ничего лишнего не сохранялось в файл
    2. Удалялся только тот объект, на который я нажму и все номера (порядковые) перестраивались на место удаленного объекта.
    3. Не было этого непонятного бага.

    :DПомогите разобраться, пожалуйста! Уже неделю голову ломаю, пол ютуба и интернета перерыл, не знаю, что делать.

    Вот код php

    PHP:
    1. <?php
    2. $name = htmlspecialchars($_POST['name']);
    3. $name = trim($name);
    4. $info = htmlspecialchars($_POST['info']);
    5. $info = trim($info);
    6. $oprice = htmlspecialchars($_POST['oprice']);
    7. $oprice = trim($oprice);
    8. $price = htmlspecialchars($_POST['price']);
    9. $price = trim($price);
    10. $idcrm = htmlspecialchars($_POST['idcrm']);
    11. $idcrm = trim($idcrm);
    12.  
    13. //Если файл существует - получаем его содержимое
    14.  
    15. $additionalArray = array(
    16.     'name' => $name,
    17.     'info' => $info,
    18.     'oprice' => $oprice,
    19.     'price' => $price,
    20.     'idcrm' => $idcrm
    21. );
    22. //open or read json data
    23. $data_results = file_get_contents('file.json');
    24. $tempArray = json_decode($data_results, true);
    25.  
    26. //append additional json to json file
    27.  
    28. $tempArray[] = $additionalArray ;
    29. $jsonData = json_encode($tempArray);
    30. $result = file_put_contents('file.json', $jsonData);
    31.  
    32.  
    33. $odel = @$_POST['delname'];
    34. if (isset($_POST['del'])){
    35.     unset($tempArray[$odel]);
    36.     file_put_contents('file.json', json_encode($tempArray, JSON_FORCE_OBJECT | JSON_NUMERIC_CHECK));
    37.     header('Location: '. $_SERVER['HTTP_REFERER']);
    38.  
    39. }
    40.  
    41. ?>

    Вот html

    HTML:
    1. <table class="table table-border">
    2.               <thead class="table-dark">
    3.                 <tr>
    4.  
    5.                   <th scope="col" style="width: 5%;"></th>
    6.                   <th scope="col" style="width: 15%;" >Название</th>
    7.                   <th scope="col" >Описание</th>
    8.                   <th scope="col" style="width: 15%;" >Цена old</th>
    9.                   <th scope="col" style="width: 15%;" >Цена new</th>
    10.                   <th scope="col" style="width: 5%;" >idCrm</th>
    11.                   <th scope="col"  style="width: 10%;">Действие</th>
    12.                 </tr>
    13.               </thead>
    14.               <tbody>
    15.                 <?php
    16.                for($i = 0; $i < count($tempArray); ++$i) {
    17.              
    18.                    ?>
    19.                     <tr>
    20.                         <th scope="row"><?php echo $i + 1 ;?></th>
    21.                         <td><?php echo $tempArray[$i][name] ?></td>
    22.                         <td><?php echo $tempArray[$i][info] ?></td>
    23.                         <td><?php echo $tempArray[$i][oprice] ?></td>
    24.                         <td><?php echo $tempArray[$i][price] ?></td>
    25.                         <td><?php echo $tempArray[$i][idcrm] ?></td>
    26.                         <td>
    27.                         <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>
    28.                         <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>
    29.                      
    30.                      
    31.                        <!-- Удаление  -->
    32.                         <div class="modal fade " id="del<?php echo $i;?>" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
    33.     <div class="modal-dialog " style="max-width: 750px;">
    34.       <div class="modal-content">
    35.         <div class="modal-header">
    36.           <h5 class="modal-title" id="exampleModalLabel">Удалить: <?php echo $tempArray[$i][name];?> ?</h5>
    37.           <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
    38.         </div>
    39.         <div class="modal-body">
    40.         <form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>"  method="post">
    41.                                                 <div class="input-group">
    42.                                                     <input type="hidden" name="delname" value="<?php echo $i; ?>">
    43.                                                 </div>
    44.                                                 <button class="btn btn-danger del" name="del">Удалить</button>
    45.                                         </div>
    46.                                         <?php
    47.  
    48. ?>
    49.                                         </form>
    50.         </div>
    51.       </div>
    52.     </div>
    53.   </div>
    54.  
    55.  
    56.  
    57.                         </td>
    58.                 </tr> <?php } ?>
    59.           </table>

    Вот я выгрузил на хостинг свою рукоблудие, дабы можно было воочию увидеть все баги =))
    https://katalog.kupi-vip.space/proba/index.php

    Вот технический файл, где можно глянуть массивы декодированные из файла json, может кому-то нужно будет.
    https://katalog.kupi-vip.space/proba/arr.php
     
  2. Slava Rozhnev

    Slava Rozhnev Новичок

    С нами с:
    6 сен 2021
    Сообщения:
    87
    Симпатии:
    26
    Адрес:
    https://phpize.online
    Не стоит городить костылей из JSON - используйте любую базу данных и будет Вам щастье
     
  3. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.548
    Симпатии:
    1.754
    1. Пост-запросы лучше обрабатывать отдельными файлами (если не используется единая точка входа/фреймворк), после обработки делать редирект куда-нибудь ещё (как раз вашу проблему решает).
    2. Ну так у вас вся логика вместе, поставьте хоть иф какой-нибудь, чтоб проверял, что мы сейчас делаем, добавляем или удаляем
    3. Ну и да, база на json-файлах, это такое себе. Лучше взять нормальную СУБД, где ооооочень умные дяди уже позаботились о таких вещах, как обработка одновременных запросов и т.п.
    --- Добавлено ---
    При использовании фреймворка/единой точки входа post и get тоже обрабатываются отдельно, но там обработчики могут находиться и в одном файле
     
  4. Сергей Курц

    Сергей Курц Новичок

    С нами с:
    7 янв 2022
    Сообщения:
    12
    Симпатии:
    0
    Благодарю за рекомендацию! Тоже так думаю. Вынесу обработчики в отдельные файлы.
    Теперь стоит вопрос, чтобы при удалении данных из json, удалялись не только значения массива, но и сам ключ объекта. И чтобы нумерация смещалась не оставляя пропусков.

    Если это возможно - дайте рекомендации.
     
  5. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.788
    Симпатии:
    646
    Это ж надо блок на GET-запрос ставить (понятно, что можно обойтись обязательными для самого POST'а проверками, но все равно придется каждый раз об этом задумываться), выдумывать разные имена файлов. Проще вилку вставить POST/не POST. Плюс при обработке связанных GET/POST часто бывает общий начальный код.
    --- Добавлено ---
    Не всегда. Есть общий обработчик, даже когда можно делать частные по методу запроса.
    --- Добавлено ---
    Это хрень. Сразу видно, что вы с норм. БД не работали. Оставьте только идентификацию. Нумерацией пусть вьюшки занимаются.
    --- Добавлено ---
    Если бы удаляли по «плавающему» номеру, а не по id-шнику, у всех бы все шло наперекосяк ;)
     
  6. Сергей Курц

    Сергей Курц Новичок

    С нами с:
    7 янв 2022
    Сообщения:
    12
    Симпатии:
    0
    Я учел советы и принял решение отказаться от JSON файла. Буду загонять данные в базу MySQL.
    В принципе это решит проблему с выводом и вторую проблему с безопасностью.

    Но столкнулся сразу же с проблемой - не могу подключиться к базе данных с помощью PDO. Хотя пользователь имеет доступ и раз 20 все перепроверил. Ошибка есть и не пропускает.

    Ошибка: SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost' (using password: YES)

    Подскажите решение данной проблемы. П.с. Установка пароля ничего не дает, всего лишь No меняется на YES.

    PHP:
    1. $host = 'localhost';
    2. $db = 'goods';
    3. $user = 'root';
    4. $pass = 'root';
    5.  
    6. try {
    7.     $pdo = new PDO("mysql:host=$host; dbname=$db", $user, $pass);
    8.   } catch (PDOException $e) {
    9.     die("Ошибка: " .$e->getMessage());
    10.   }
     
    #6 Сергей Курц, 9 янв 2022
    Последнее редактирование: 9 янв 2022
  7. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.788
    Симпатии:
    646
    Наверное, лучше создать отдельную тему. У root-а точно пароль root? И возьмите за правило вместе с БД сразу создавать (одноименного) пользователя, из-под которого и работать с этой БД (у пользователя права только на работу с этой БД; можно даже их ограничивать).
     
  8. Сергей Курц

    Сергей Курц Новичок

    С нами с:
    7 янв 2022
    Сообщения:
    12
    Симпатии:
    0
    В общем проблема сама собой решилась. После 100500 перезагрузок mysql и 100500 изменений пользователей, ошибка исчезла. Что там конкретно было не так - уже сложно сказать, но вроде пока работает :D:D:D
    --- Добавлено ---
    Каких я пользователей не назначал - не работало. Начало работать, когда назначил того, под которым зашел в бд, хотя его не правил. В общем я не понимаю, почему не работало с другими пользователями.
     
  9. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.788
    Симпатии:
    646
    Из-под рута создаете БД и одноименного пользователя с правами для работы с этой БД. Потом работаете с БД из-под соотв. пользователя.
     
  10. Сергей Курц

    Сергей Курц Новичок

    С нами с:
    7 янв 2022
    Сообщения:
    12
    Симпатии:
    0
    Благодарю за совет