【问题标题】:Why does this SQL UPDATE query not work with a variable for WHERE?为什么此 SQL UPDATE 查询不适用于 WHERE 的变量?
【发布时间】:2020-05-12 17:09:34
【问题描述】:

这是我在 Stack Overflow 上的第一篇文章。我知道这个问题已经被问过很多次了。我经历了很多答案,尝试了所有答案(显然正确的方法除外)并且不知道该尝试什么了。

我有一个 SQL 表,其中每一行都有一个“编辑”按钮。单击它时,我将所选行的 id 传递给edit.php。在那里,我得到它并使用表单中的用户输入根据 id 更新给定的行。第一列是 id,设置为AUTO_INCREMENT

顺便说一句,无论我使用WHERE id=$id"; 还是WHERE id='$id'";,我都会遇到同样的错误

我认为最接近正确方法的代码如下,并在代码下方生成错误消息:

<html>
    <title>
        Video Archiv - New
    </title>
    
    <body>
        <?php
            include("connect.php"); 
            $id=$_GET['id'];
            echo "Details von Video #$id editieren:<br /><br />";
            
            if(isset($_POST['update']))
            {
                $sql =  "UPDATE VideoArchiv             
                        SET ('".$_POST["titel"]."','".$_POST["schauspieler"]."')
                        WHERE id=$id";

                        $result = mysqli_query($connect,$sql);

                if (mysqli_query($connect,$sql) === TRUE) 
                {
                    echo "Record updated successfully";
                } 
                else 
                {
                    echo "Error updating record: " . $connect->error;
                }
            }
            ?>

        <form action="edit.php" method="post"> 
            
            <label> Titel:</label><br/>
            <input type="text" name="titel" required><br/>

            <label>Schauspieler</label><br/>
            <input type="text" name="schauspieler" required><br/>
            <br />
            <button type="submit" name="update">Speichern</button>
                
        </form>

        <?php
            include("back.php");
        ?>
    </body>
</html> 

错误信息:

错误更新记录:您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 2 行的 '('a','d') WHERE id=9' 附近使用正确的语法

非常感谢您的帮助,并对重复的问题感到抱歉,但我真的找不到解决方案,非常绝望。

更新:

下面的代码给出了这个错误:

致命错误:未捕获的错误:在 /homepages/25/d72758610/htdocs/multimedia/edit.php:30 中调用 bool 上的成员函数 bind_param() 堆栈跟踪:在 /homepages/25 中抛出 #0 {main} /d72758610/htdocs/multimedia/edit.php 第 30 行

<html>
    <title>
        Video Archiv - New
    </title>
    
    <body>
        <?php
            include("connect.php"); 
            $id=$_GET['id'];
            $title = $_POST["titel"];
            $schauspieler = $_POST["schauspieler"];

            if(empty($title))
            {
                echo "error";
            }
            elseif(empty($schauspieler))
            {
                echo "error";
            }
            else
            {
                $sql = "UPDATE users SET title=?, schauspieler=? WHERE id=?";
                $stmt= $connect->prepare($sql);
                $stmt->bind_param("ssi", $title, $schauspieler, $id);
                if($stmt->execute())
                {
                      echo "Succes";
                }
                else
                {
                  echo "something went wromg";
                }
            }
            ?>

        <form action="edit.php" method="post"> 
            
            <label> Titel:</label><br/>
            <input type="text" name="titel" required><br/>

            <label>Schauspieler</label><br/>
            <input type="text" name="schauspieler" required><br/>
            <br />
            <button type="submit" name="update">Speichern</button>
                
        </form>

        <?php
            include("back.php");
        ?>
    </body>
</html> 

【问题讨论】:

  • 失败的是 SET,而不是 WHERE。
  • 我认为你的 where 不是问题 - 看起来这是你正在做你的 set 的事实,就像你做 insert dev.mysql.com/doc/refman/5.7/en/set-variable.html 一样 - 请注意 SQL 注入代码中的漏洞
  • 相关:警告:您的代码容易受到 SQL 注入攻击。您应该使用参数化查询和准备好的语句来帮助防止攻击者通过使用恶意输入值来破坏您的数据库。 bobby-tables.com 给出了风险解释,以及一些如何使用 PHP / mysqli 安全地编写查询的示例。 切勿将未经处理的数据直接插入您的 SQL。按照您现在编写代码的方式,有人可以轻松窃取、错误更改甚至删除您的数据。
  • 错误消息告诉您“检查与您的 MySQL 服务器版本相对应的手册以获取正确的语法使用”。你查看手册了吗:dev.mysql.com/doc/refman/8.0/en/update.html
  • @Jocelyn 是的,我当然检查了手册。但是,由于这行代码适用于 UPDATE,我认为它也适用于 UPDATE

标签: php sql mysqli sql-update


【解决方案1】:

可以使用以下查询:

UPDATE VideoArchiv SET columnname1 = '".$_POST["titel"]."', columnname2 = '".$_POST["schauspieler"]."' WHERE id=$id

【讨论】:

  • 是的,这可以解决基本的语法问题。尽管如果您展示的版本没有明显的安全漏洞,对 OP 和其他读者会更有帮助 - 而且如果 POST 变量包含撇号之类的内容,它很容易出现额外的意外语法错误。
【解决方案2】:

查询中没有给出列名

更新表名 放 column_name1 = expr1, column_name2 = expr2, ... [在哪里 条件];

因此,您的查询将是这样的,并检查数据库中的列名:

$sql =  "UPDATE VideoArchiv             
                SET titel='".$_POST["titel"]."',schauspieler='".$_POST["schauspieler"]."'
                WHERE id=$id";

注意:这是sql易受攻击的,所以请添加mysql真正的转义函数(https://www.php.net/manual/en/function.mysql-real-escape-string.php)或将其转换为pdo。

【讨论】:

  • Don't have 转换为 PDO,而 PDO 做得更好,mysqli 确实提供了准备好的语句 - 你的链接也是 mysql 真正的转义,而不是 mysql
【解决方案3】:

您遇到的问题是您的代码没有正确使用SET,您目前有以下情况;

$sql =  "UPDATE VideoArchiv             
    SET ('".$_POST["titel"]."','".$_POST["schauspieler"]."')
        WHERE id=$id";

就像INSERT 一样使用它

要纠正当前的问题,只需更改为;

$sql =  "UPDATE VideoArchiv             
        SET field1 = '".$_POST["titel"]."',
            field2 = '".$_POST["schauspieler"]."'
        WHERE id=$id";

但是这个 odes 让您容易受到 SQL 注入攻击,要快速轻松地解决这个问题,像下面这样简单的事情会有所帮助;

$id = mysqli_real_escape_string($connect, $_POST["id"]);
$titel = mysqli_real_escape_string($connect, $_POST["titel"]);
$schauspieler = mysqli_real_escape_string($connect, $_POST["schauspieler"]);

$sql =  "UPDATE VideoArchiv             
        SET field1 = '{$titel}',
            field2 = '{$schauspieler}'
        WHERE id=$id";

我建议阅读准备好的语句,因为这样会更安全

我知道在这篇文章之前已经对手头的问题有正确的答案,但没有人提到注入以及如何解决(即使是像这里这样的软方式)

【讨论】:

  • 非常感谢您指出SQL注入问题。一旦我以这种方式工作,我将进入与安全相关的内容(我需要先了解基本的基础知识)。不幸的是,您的任何建议都没有解决问题,我仍然遇到同样的错误。 SQL 版本是 MySQL 5.7
  • @TheToastMachine - 您可以编辑您的问题以包含新查询吗?这会让我们看到你在做什么
【解决方案4】:

避免 sql 注入和使用最新代码非常简单,并且 您的 SQL 语法有错误

这是一个例子:

   include("connect.php"); 
    $id=$_GET['id'];
    $title = $_POST["titel"];
    $schauspieler = $_POST["schauspieler"];

    if(empty($title)){
    echo "error";
    }elseif(empty($schauspieler)){
    echo "error";
    }else{

    $sql = "UPDATE VideoArchiv SET title=?, schauspieler=? WHERE id=?";
    $stmt= $connect->prepare($sql);
    $stmt->bind_param("ssi", $title, $schauspieler, $id);
    if($stmt->execute()){
      echo "Succes";
    }else{
      echo "something went wromg";
    }

    }

查看更多信息:https://phpdelusions.net/mysqli_examples/update

更新:第一个代码适合你,但如果你仍然想使用程序方式,那么我们这个:

include("connect.php");
if ($_SERVER["REQUEST_METHOD"] == "POST") {

//Check if we get id 
$Testid = $_GET['id'];
if(empty($Testid)){
    echo "id is empty";
}else{
    $id = $_GET['id'];
}


$title = $_POST["titel"];
$schauspieler = $_POST["schauspieler"];

    if(empty($title )){
        echo "error". $title; 
    }elseif(empty($schauspieler)){
        echo "error". $schauspieler;
    }else{
       $sql = "UPDATE VideoArchiv SET title=?, schauspieler=? WHERE id=?";
       $stmt = mysqli_prepare($connect, $sql);
       mysqli_stmt_bind_param($stmt, 'ssi', $title, $schauspieler, $id);
       mysqli_stmt_execute($stmt); 
    }
}

<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">

	<label> Titel:</label><br/>
	<input type="text" name="titel" required><br/>

	<label>Schauspieler</label><br/>
	<input type="text" name="schauspieler" required><br/>
	<br />
	<button type="submit" name="update">Speichern</button>

</form>

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-27
相关资源
最近更新 更多