【问题标题】:SQL Injection: trying to avoid it but got an errorSQL注入:试图避免它但得到一个错误
【发布时间】:2017-03-08 00:39:28
【问题描述】:

所以这只是我的代码的一部分,但却是唯一相关的事情:

if ($check == 0) {     
                    $host = "localhost";
                    $user = "root";
                    $pass = "";
                    $db = "myfirstdb";
                    $connect = new mysqli($host,$user,$pass,$db);
                    if ($connect->connect_error){ 
                        die("Connection failed: " . $connect->connect_error);
                    } else {
                        echo "Connected successfully!";
                    }

                    //$sql = "INSERT INTO table1 (firstname , lastname , phone , email , date) VALUES (:fname, :lname, :phone, :email, :date)";
                    $secure = $db->prepare("INSERT INTO table1 (firstname , lastname , phone , email , date) VALUES (:fname, :lname, :phone, :email, :date)");
                    $secure->bindParam(':fname' , $firstname);
                    $secure->bindParam(':lname' , $lastname);
                    $secure->bindParam(':phone' , $phone);
                    $secure->bindParam(':email' , $email);
                    $secure->bindParam(':date' , $date);
                    $secure->execute();
                    /*if ($connect->query($sql) === TRUE) {
                        echo "New record created successfully";
                    } else {
                        echo "Error: " . $sql . "<br>" . $connect->error;
                    }*/

                    $connect->close(); 

我遇到的问题是每当我执行代码时都会弹出一个错误:

致命错误:未捕获的错误:调用 C:\xampp\htdocs\example\Index.php:206 中字符串上的成员函数 prepare() 堆栈跟踪:#0 {main} 在 C:\xampp\htdocs 中抛出\example\Index.php 第 206 行

我正在尝试通过使用此代码来避免 SQL 注入,但我不确定我是否理解它。

【问题讨论】:

  • 您的准备​​失败,您未能检查失败,并继续传播错误。特别是:mysqli 不支持命名占位符。您正在尝试将 PDO 语义与完全不同的库一起使用。永远不要永远假设对外部资源的操作会成功。始终假设失败,检查失败,并将成功视为惊喜。
  • 你没有 $db 变量,你有 $connect。
  • 我也没有看到你传入的变量是在哪里设置的。
  • 变量已设置,但我没有粘贴整个代码,因为我认为它不相关。
  • @MarcB 根据php mysqli,这不仅仅是 PDO 语义。 mysqli可以这样使用。

标签: php sql


【解决方案1】:

您没有准备关于正确变量的语句。你需要做的:

$connect->prepare("INSERT INTO table1 (firstname , lastname , phone , email , date) VALUES (:fname, :lname, :phone, :email, :date)");

编辑:

  $db = "myfirstdb";
  $connect = new mysqli($host,$user,$pass,$db);

您的 Object 是您设置为“新类”的变量,因此在这种情况下,您的对象是 $connect 这是一个 new mysqli 类实例.您的原始脚本(导致错误)使用了 $db 变量,该变量是 string 而不是 Object。

您只能在对象上使用-&gt;prepare(并使用-&gt; 语法)。

【讨论】:

    【解决方案2】:

    除了useyourillusiontoo's 答案之外,正如 Marc B 在 cmets 中指出的那样,您显示的代码在 MySQLi 和 PDO 之间存在混淆。

    存在各种差异,您基本上是在尝试将六边形装入七边形形状的孔中。 MySQLi 使用? 作为占位符,PDO 使用命名占位符,就像您在脚本中使用的那样。

    例如你的代码是:

     $connect = new mysqli($host,$user,$pass,$db);
    

    这意味着您正在使用mysqli DB 处理程序,因此您需要将:placeholder 替换为?,然后按照它们在SQL 字符串中出现的顺序设置变量 ,如:

       $secure = $connect->prepare("INSERT INTO table1 
                        (firstname , lastname , phone , email , date)
                        VALUES (?, ?, ?, ?, ?)");
       $secure->bind_param('sssss' , 
                          $firstname, $lastname , $phone, $email ,$date);
    

    所以第一个?取变量类型声明后的第一个变量(sesssssss的集合),所以第一个?在这个实例中指的是$firstname。 ? 的数量和绑定参数中给定的变量数量必须匹配。

    注意,对于 MySQLi,类方法是 -&gt;bind_param,而不是 -&gt;bindParam。

    您需要read up a bit 了解MySQLi 和PDO 的一般语法差异,尤其是the first paramter 上bind_param 的含义。

    要在你的脚本中使用PDO,你可以将你的类设置为:

    $connect = new PDO(...$details...);
    

    我认为如果你可以使用 MySQLi,这不保证你也可以运行 PDO。他们是不同的。您可以在脚本 here 中阅读有关正确 PDO 设置的更多信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-09
      • 2017-12-02
      • 2022-01-27
      • 1970-01-01
      • 1970-01-01
      • 2011-01-13
      • 2018-10-14
      • 2014-06-16
      相关资源
      最近更新 更多