【问题标题】:mySQL auto-increment + auto adjust id by dynamicly deleting table content via PHP?通过PHP动态删除表格内容的mySQL自动增量+自动调整id?
【发布时间】:2019-06-09 15:21:04
【问题描述】:

我目前正在尝试构建一个“ToDo-App”,它可以让我将INSERT 文本输入数据库,然后将显示该数据库。有一个“功能”可以根据他们的ID删除内容。

如果我在我的应用程序中输入两个任务,我会得到两个表记录 ID 1 和 2。当我删除记录 1 时,ID 为 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 输出 MySQL 仪表板

【问题讨论】:

  • 你想输入列表键而不是 id 吗?
  • 是的,因为列表键会自行调整。如果我有 2 个列表,并且我删除了第一个列表,那么第 2 个列表将变为第 1 个列表。所以如果我可以通过列表键(有序列表)删除列表,那将是完美的。
  • 为什么需要文本输入字段?通常我们使用复选框来标记项目,并有一些操作按钮,如删除、编辑等。就像在您的 MySQL 仪表板中一样。
  • 那也很酷,但我无法想象如何编写代码..
  • 建议对数据库表记录的唯一性使用主键,而不是应用程序级别的视图排序。我将在表中创建另一个名为order 的字段。因此,删除将基于order 字段,而不是id 字段。请记住,如果您必须上下移动任务,id 字段将很快显示自己不适合此任务! ;-) 排序/过滤也可能会产生异常结果(随着表的增长和向最大表行增长)。

标签: php mysql increment


【解决方案1】:

列表的键是数据库中的'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");
    }

【讨论】:

  • 那时我无法删除列表。它出现一毫秒左右,然后又回到原来的位置。
  • 这种策略对于添加完整的操作(添加、删除和移动)并不是一个好兆头。对于这样的问题,DELETE 语句中肯定应该有一个WHERE 子句。在这种情况下,条件应指向order 字段中的特定值。 LIMIT 1 之后就可以了。您的删除过程过于复杂且效率低下。
【解决方案2】:

正如评论中所讨论的,您可以将多个复选框组成一个数组参数:&lt;input name="theName[1]"&gt; 带有显式键,name="theName[]" 带有隐式键。

此外,您应该使用准备好的语句来防止 SQL 注入攻击。想象一下,攻击者发送的请求在字段中带有单引号 ',即他终止了 SQL 字符串分隔符,并添加了任意 SQL 代码。准备好的语句使用占位符,参数单独发送。

您还应该处理错误。在下面的代码中,错误以 HTML 格式输出,但是,您应该在流中定义自己的记录器函数,而不仅仅是 echo。这可以在开发服务器上输出 HTML,但在生产服务器上记录到磁盘。

这是一个使用 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>

【讨论】:

  • 好的,我明天花点时间研究一下你的答案。带有错误报告等的代码效果很好,但它和我的一样,就像它也有数字问题一样。但我会检查你到底写了什么,就像明天一样^^
  • @Tom 数字是数据库ID,普通枚举。
  • 尽管如此,我什至再次简化了这一点,因为复选框值不用于其他目的。它现在传输 id 而不是数组键。
  • 由于某种原因,它一直告诉我:“解析错误:语法错误,第 133 行 C:\xampp\htdocs\todo\index.php 中的文件意外结束”我刚刚添加了一个结束 和
猜你喜欢
  • 2012-11-18
  • 2011-01-13
  • 2015-07-05
  • 1970-01-01
  • 2011-07-03
  • 2013-06-23
  • 2020-03-29
相关资源
最近更新 更多