MySQL автоинкремент + автоматическая настройка идентификатора путем динамического удаления содержимого таблицы через PHP? - PullRequest
0 голосов
/ 15 января 2019

В настоящее время я пытаюсь создать «ToDo-App», которое позволяет мне INSERT текст в базу данных, которая затем будет отображаться. Существует «функция» удаления контента на основе их ID.

Если я ввожу две задачи в свое приложение, я получаю две записи таблицы с ID 1 и 2. Когда я удаляю запись 1, запись с идентификатором 2 все еще существует. Таким образом, запись с ID 2 указана в качестве первого элемента в списке дел.

Я должен ввести «2» в «поле удаления ввода», чтобы удалить первый элемент из списка! Как я могу получить это быть в синхронизации? Подходит ли поле ID для поддержания логического / прикладного уровня задач?

<!doctype HTML>
<html>

<head>
    <meta charset="utf-8">
    <title>ToDo-APP</title>
    <link rel="stylesheet" href="css/Lil-Helper.css">
    <link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet">
    <link rel="stylesheet" href="css/webfonts/all.css">
    <link rel="stylesheet" href="css/own.css">

</head>


<?php
    $con = mysqli_connect("","root","","todo");
    $sql = "SELECT text FROM work";
    $res = mysqli_query($con, $sql);


    if(isset($_POST["text"]))
    {
        $eingabe = $_POST["text"];
        $query = "INSERT INTO work(text) VALUES('$eingabe')";
        mysqli_query($con, $query);
        header("Refresh:0");
    }
    else
    {
        echo "";
    }



    if(isset($_POST["del"]))
    {
        $del = $_POST["del"];
        $res = mysqli_query($con, $sql);
        $sql2 = "DELETE FROM `work` WHERE `work`.`id` = $del";
        mysqli_query($con, $sql2);
        header("Refresh:0");
    }
    else 
    {
        echo "";
    }

?>
<body>
    <header class="lil-menu lil-flex lil-flex-center align-center">
        <a href="index.html" class="lil-brand">
            <h3>To-Do</h3>
        </a>
        <a class="lil-menu-item currentLink" href="index.html">ToDo</a>
        <a class="lil-menu-item" href="#archive">Archiv</a>
        <a class="lil-menu-item" href="#Sprachen">Sprachen</a>
    </header>

    <div class="main">
        <div class="lil-box">
            <h3 class="lil-font-rot lil-big-font lil-space lil-font-style" style="font-size: 4rem;">ToDo</h3>
              <div class="lil-box">
            <form action="index.php" method="post">
                <input  class="lil-input" name="text" type="text">
                <input type="submit" class="lil-button-green" value="Hinzufügen">

            </form>

                <ol id="liste" class="lil-list">
                    <?php
                    while($dsatz = mysqli_fetch_assoc($res))
                    {
                        echo "<li>" .$dsatz["text"] ."</li>";
                    }
                    ?>
                </ol>
            <form id="form" action="index.php" method="post">
                <input  class="lil-input" name="del" type="text">
                <input type="submit" class="lil-button-red lil-button-small" value="   Löschen   ">
            </form>
            </div>       
        </div>
    </div>

<script src="js/jquery-3.3.1.min.js"></script>

<script>

    var anzahl = $("#liste li").length; 
    if(anzahl < 1)
    {
        $("#form").hide();
    }
    else
    {
        $("form").show();
    }

    </script>
</body>

</html>

Картинки:

Вывод HTML HTML Output MySQL Dashboard MySQL Dashboard

Ответы [ 2 ]

0 голосов
/ 15 января 2019

Как обсуждалось в комментарии, у вас может быть несколько флажков, формирующих параметр массива: <input name="theName[1]"> с явным ключом и name="theName[]" с неявным ключом.

Более того, вы должны использовать подготовленные операторы для предотвращения атак SQL-инъекций. Представьте, что злоумышленник отправляет запрос с одинарной кавычкой ' в поле, т. Е. Он завершает разделитель строк SQL и добавляет произвольный код SQL. Подготовленные операторы используют заполнители, а параметры отправляются отдельно.

Вы также должны обрабатывать ошибки. В приведенном ниже коде ошибки выводятся в виде HTML, однако вы должны определить свою собственную функцию ведения журнала, а не просто echo в поток. Это может выводить HTML на серверы разработки, но записывать на диск на производственных серверах.

Это рабочий пример, протестированный на PHP7.3 с MariaDB 10:

<!DOCTYPE HTML>
<html lang="de">

<head>
  <meta charset="utf-8">
  <title>ToDo-APP</title>
  <link rel="stylesheet" href="css/Lil-Helper.css">
  <link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet">
  <link rel="stylesheet" href="css/webfonts/all.css">
  <link rel="stylesheet" href="css/own.css">
  <style>
    #frm-tasks button
    {
      padding: 0 18px;
    }
  </style>
</head>

<body>

<?php
  mysqli_report(MYSQLI_REPORT_STRICT);
  try
  {
    $con = new mysqli('localhost', 'testuser', 'testpasswd', 'testdb');

    $action = $_POST['action'] ?? 'list';

    if(!empty($_POST["text"]))
    {
      $eingabe = $_POST["text"];
      try
      {
        $stmt = $con->prepare('INSERT INTO work(text) VALUES(?)');
        $stmt->bind_param('s', $_POST["text"]);
        $stmt->execute();
      }
      catch (mysqli_sql_exception $e)
      {
        $msg = $e->getMessage();
        echo "<div>Error processing statement: $msg;</div>";
      }
    }


    if('del' === $action && isset($_POST['rows']) && is_array($_POST['rows']))
    {
      try{
        $stmt = $con->prepare('DELETE FROM `work` WHERE `work`.`id` = ?');
        $stmt->bind_param('i', $row);

        foreach ($_POST['rows'] as $row)
        {
          $stmt->execute();
          if($e = $stmt->error)
            echo "<div>DB Error: $e</div>";

        }
      }
      catch (mysqli_sql_exception $e)
      {
        $msg = $e->getMessage();
        echo "<div>Error processing statement: $msg;</div>";
      }
    }

?>
  <header class="lil-menu lil-flex lil-flex-center align-center">
    <a href="index.html" class="lil-brand">
      <h3>To-Do</h3>
    </a>
    <a class="lil-menu-item currentLink" href="index.html">ToDo</a>
    <a class="lil-menu-item" href="#archive">Archiv</a>
    <a class="lil-menu-item" href="#Sprachen">Sprachen</a>
  </header>

  <div class="main">
    <div class="lil-box">
      <h3 class="lil-font-rot lil-big-font lil-space lil-font-style" style="font-size: 4rem;">ToDo</h3>
      <div class="lil-box">
        <!--form action="index.php" method="post"-->
        <form id="frm-tasks" action="" method="post">
          <input  class="lil-input" name="text" type="text">
          <button type="submit" class="lil-button-green" name="action" value="add">Hinzufügen</button>
<?php
    try
    {
      $res = $con->query('SELECT id, text FROM work');
      if(0 < $res->num_rows)
      {
?>
          <table>
            <thead>
              <tr>
                <th></th><th>ID</th> <th>Aufgabe</th>
              </tr>
            </thead>
            <tbody>
<?php
        while($dsatz = mysqli_fetch_object($res))
        {
?>
              <tr>
                <td><input type="checkbox" name="rows[]" value="<?php echo $dsatz->id;?>"></td><td><?php echo $dsatz->id;?></td> <td><?php echo $dsatz->text;?></td>
              </tr>
<?php
        }
?>
            </tbody>
          </table>

          <button type="submit" class="lil-button-red lil-button-small" name="action" value="del">Löschen</button>
<?php
      }
    }
    catch (mysqli_sql_exception $e)
    {
      $msg = $e->getMessage();
      echo "<div>Error processing statement: $e->msg;</div>";
    }
?>
        </form>
      </div>
    </div>
  </div>

  <!-- not needed atm  script src="js/jquery-3.3.1.min.js"></script-->

  <h2>POST</h2>
<?php
    var_dump($_POST);
  }
  catch (mysqli_sql_exception $e)
  {
    $msg = $e->getMessage();
    echo "<div>Error connecting DB: $msg;</div>";
  }
?>
</body>

</html>
0 голосов
/ 15 января 2019

Ключом списка является 'th' в базе данных, поэтому просто фиксируем ограничения

Заменить

if(isset($_POST["del"]))
    {
        $del = $_POST["del"];
        $res = mysqli_query($con, $sql);
        $sql2 = "DELETE FROM `work` WHERE `work`.`id` = $del";
        mysqli_query($con, $sql2);
        header("Refresh:0");
    }

С

if(isset($_POST["del"]))
    {
        $del = $_POST["del"];
        $res = mysqli_query($con, $sql);
        $sql2 = "DELETE FROM `work` LIMIT 1 OFFSET ".array_search($del, mysqli_fetch_assoc($res));
        mysqli_query($con, $sql2);
        header("Refresh:0");
    }
...