SQL注入:试图避免它但是出错了

时间:2016-10-25 20:10:25

标签: php sql

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

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中调用字符串上的成员函数prepare():206堆栈跟踪:#0 {main}抛出C:\ xampp \ htdocs第206行的例子\ Index.php

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

2 个答案:

答案 0 :(得分:2)

您没有准备关于正确变量的声明。你需要这样做:

$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);

您的对象是您设置为“新课程”的可变对象,因此在这种情况下,您的对象为$connect,这是 {{1类实例。您的原始脚本(导致错误)使用mysqli变量,该变量是字符串而非Object。

Objects 上只能$db(并使用->prepare语法)。

答案 1 :(得分:1)

除了useyourillusiontoo's回答之外,正如Marc B在评论中指出的那样,您显示的代码在MySQLiPDO之间混淆。

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

例如,您的代码是:

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

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

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

因此,第一个?获取变量类型声明后的第一个变量(sess sssss的集合),因此在此实例中,首先?引用$firstname?的数量和绑定参数中给出的变量数必须匹配。

  

请注意,MySQLi的类方法为->bind_param,而不是->bindParam

您需要read up a bit了解MySQLiPDO的一般语法差异,尤其是bind_paramthe first paramter的含义。

要在脚本中使用PDO,请将您的课程设置为:

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

我认为如果您可以使用MySQLi,那么保证您也可以运行PDO。他们与众不同。您可以在脚本 here 中详细了解正确的PDO设置。