简体   繁体   English

通过PHP动态删除表内容,mySQL自动递增+自动调整id?

[英]mySQL auto-increment + auto adjust id by dynamicly deleting table content via PHP?

I am currently trying to build a "ToDo-App" which lets me INSERT text into a database, which will then be displayed.目前我正在试图建立一个“待办事项应用内广告”,这让我INSERT文本到数据库,然后将被显示。 There is a "feature" to delete content based on their ID .有一个“功能”可以根据他们的ID删除内容。

If I input two tasks into my application, I get two table records with ID 1 and 2. When I delete record 1, the record with ID 2 still exists.如果我在我的应用程序中输入两个任务,我会得到两个ID 1 和 2 的表记录。当我删除记录 1 时,ID 为 2 的记录仍然存在。 Thus, the record with ID 2 is listed as the first item in the to-do list.因此, ID 2 的记录被列为待办事项列表中的第一项。

I have to enter "2" in the "delete input field" to delete the first item from the list!我必须在“删除输入字段”中输入“2”才能从列表中删除第一项! How can I get this to be in sync?我怎样才能让它同步? Is the ID field appropriate for maintaining the logical / application level order of the tasks? 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>

The pictures:图片:

HTML Output HTML 输出HTML 输出 MySQL Dashboard MySQL仪表盘MySQL仪表盘

As discussed in the comment, you can have multiple checkboxes forming an array parameter: <input name="theName[1]"> with explicit key and name="theName[]" with implicit keys.正如评论中所讨论的,您可以有多个复选框形成一个数组参数:带有显式键的<input name="theName[1]">和带有隐式键的name="theName[]"

Further more, you should use prepared statements to prevent SQL injection attacks.此外,您应该使用准备好的语句来防止 SQL 注入攻击。 Imagine an attacker sends a request with a single quote ' in the field, ie he terminates the SQL string delimiter, and adds arbitrary SQL code.想象一下,攻击者在字段中发送一个带有单引号'的请求,即他终止 SQL 字符串分隔符,并添加任意 SQL 代码。 Prepared statements use placeholders and the parameters are sent separately.准备好的语句使用占位符,参数单独发送。

You should also handle errors.您还应该处理错误。 In the code below errors are output as HTML, however, you should define your own logger function rather than just echo into the stream.在下面的代码中,错误输出为 HTML,但是,您应该定义自己的记录器函数,而不仅仅是echo到流中。 This can output HTML on development servers but log to disk on production servers.这可以在开发服务器上输出 HTML,但在生产服务器上登录到磁盘。

This is a working example tested on PHP7.3 with MariaDB 10:这是一个使用 MariaDB 10 在 PHP7.3 上测试的工作示例:

<!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>

The key of the list is the 'th' in the database so just fixing limits列表的键是数据库中的“th”,因此只需修复限制

Replace代替

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");
    }

With

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");
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM