【问题标题】:Input values become number automatically when insert to MySQL插入 MySQL 时输入值自动变为数字
【发布时间】:2019-05-30 07:06:42
【问题描述】:

我正在尝试插入我的数据库表中。我是用ajax做的。

这是我的代码:

$(document).on('click','.add', function(){
    var id = $(this).attr("id");
    var DT = $('#DT'+id).val(); 
    var SV = $('.search_text').val(); // store input value
    var action = "add";


    $.ajax({

        url:"action.php",
        method:"POST",
        data:{DT:DT, SV:SV,action:action,id:id},
        success: function(data){

            alert("success");               

        },
        error: function(){

        alert("error action");

        }

    });

});

数据将指向action.php。这是action.php的代码:

if (isset($_POST['action'])) {

        if($_POST["action"] == "add") {


            $insert_dtb = mysqli_query($con, "INSERT INTO table_dtb(SV, DT, DK, NH, ttDK, ngTT) 
            value($_POST[SV],$_POST[DT],now(),$_POST[SV],'1',now());"); 


        }
}

但我在 SV 变量中的输入值在插入表时变为数字。

示例:如果我输入 0153222,那么在表 table_dtb 的 SV 列中它只有 153222,我不能在 SV 列中输入字符。

虽然我将 table_dtb 中的列 SV 设置为 varchar(9),但它并没有像我预期的那样工作。

【问题讨论】:

  • sql注入的圣母。
  • Kit Harrington:Sql 注入来了!!!
  • 使用参数化查询,问题就会消失(同时也会修复sql注入漏洞)
  • 由于您没有使用准备好的语句(顺便说一句,您确实应该这样做),请尝试回显您的插入查询,以确保它插入的是您认为的内容。其他东西可能会删除开头的 0。否则,我猜这是因为变量没有被引用,所以 MySQL 将值视为数字而不是字符串,并删除 0。使用准备好的语句和参数绑定会解决的。
  • 请注意,存在 mysqli/PDO 包装器可以自动为您处理准备好的语句。比如我的班级GrumpyPDO,你的代码就会变成$db->run("INSERT INTO table_dtb (SV, DT, DK, NH, ttDK, ngTT) VALUES (?, ?, now(), ?, '1', now())", [$_POST['sv'], $_POST['dt'], $_POST['sv']]);,这样就不会被SQL注入了。

标签: php jquery mysql sql ajax


【解决方案1】:

您将$_POST[SV] 的值传递了两次,而NH 的值大概应该是您想要的任何值。尽管如此,您不仅会使用准备好的语句捕捉到这一点,而且您只是在为自己当前的代码进行 SQL 注入。

看看这个例子:

<?php
try {
  /* setup your database configuration */
  $config =  array(
    "host" => "127.0.0.1",
    "username" => "root",
    "password" => "",
    "name" => "db_name"
  );
  $dsn = "mysql:dbname=$config[name];host=$config[host];charset=utf8mb4";
  $db = new PDO($dsn, $config["username"], $config["password"]);
  $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

  /* prepare the SQL statement */
  $stmt = $db->prepare("
    INSERT INTO `table_dtb` (
      `SV`, `DT`, `DK`, `NH`, `ttDK`, `ngTT`
    ) VALUES (
      :sv, :dt, NOW(), :nh, '1', NOW()
    );
  ");

  /* execute the statement passing the parameterized values */
  $stmt->execute(array(
    ":sv" => $_POST["SV"],
    ":dt" => $_POST["DT"],
    ":nh" => $_POST["NH"]
  ));
} catch(PDOException $ex) {
  /* pdo exception */
} catch (Exception $e) {
  /* php exception */
}
?>

为了解释代码的作用,您可以将其分解为 4 个不同的部分。第一部分是 Try/Catch 异常处理程序。任何时候你有一段可能失败的代码,你应该把它包装在 Try/Catch 处理程序中,它的作用是说“我将尝试执行这段代码,但如果它失败了,那么我想处理随之而来的错误。”有两个单独的 catch 块的原因是您有一个处理数据库错误,另一个处理您的正常 PHP 错误。如果您想要对错误做的只是告诉用户发生了错误,只需使用 echo 语句。但是,如果您正在调试并且错误消息是相关的,那么您可以通过调用 getMessage 函数来获取执行的消息。

第二部分是数据库配置。从 PHP 5 开始,PHP Data Objects 用于处理您的数据库操作。我个人设置配置数组的原因是因为对我来说它更容易调试和阅读,尽管它不是完全必要的。重要的部分是您创建一个新的 PDO 对象。

第三部分是使用参数化值准备 SQL 语句。由于 SQL 语句中忽略了空格,并且 PHP 允许字符串文字中的行继续,因此您可以通过对 SQL 语句的不同段使用单独的行来格式化 SQL 语句以获得更好的可读性。前面有: 前缀的值的基本思想是,它们代表一个不直接存储在 SQL 字符串中的值。

第四部分是执行参数化查询。单独调用 execute 函数会运行 SQL 语句,但是因为您已经在 SQL 查询中传递了参数,所以还需要传递要发送的值。在这种情况下,我们已经命名了参数,因此在关联数组中,我们将参数的名称指定为键,然后将要传递的值作为值分配。

希望这可以为您清除代码,如果您有任何问题,请随时提出。

【讨论】:

  • 这实际上并没有比问题中的 cmets 多说什么,因为即使您显示了正确的代码来执行此操作,您也没有解释代码是如何工作的,或者您为什么要这样做你在做。编辑:不是我的 DV
  • @GrumpyCrouton - 我尝试通过代码中的 cmets 来解释代码。
  • 也许,非常模糊。您没有解释为什么要设置这些特定属性,或者占位符如何为变量工作,或者try -&gt; catch 是如何工作的,或者为什么你有多个捕获。您的代码和 OP 的代码相隔数光年。如果 OP 已经使用了这些东西,那将是一回事,但他们没有。这是一个可能被复制并粘贴到 OP 代码中的答案示例,该代码有效,但他们实际上并没有获得关于正确处理这些事情的方法的任何知识。在我看来,这使得这个答案“没有用”。
  • @GrumpyCrouton - 很公平,我已经详细说明了我的答案。
  • 我认为你应该再读一遍他们的问题; I've commented about 在他们的(不清楚的)问题下,没有人发现的东西。注意:不是我的反对票。
猜你喜欢
  • 1970-01-01
  • 2019-03-15
  • 1970-01-01
  • 1970-01-01
  • 2021-10-13
  • 2021-08-03
  • 1970-01-01
  • 2012-01-29
  • 1970-01-01
相关资源
最近更新 更多