【问题标题】:How do I turn the following INSERT into a prepared statement so that its secure?如何将以下 INSERT 转换为准备好的语句以确保其安全?
【发布时间】:2010-09-15 11:21:57
【问题描述】:

我正在努力理解准备好的陈述。

基本上,我会像往常一样进行插入:

$sql = '
    INSERT INTO customers 
      (customer_first, customer_last, customer_address, customer_email)
    VALUES
      (' . mysql_real_escape_string($_POST['customer_first']) . ', 
      ' . mysql_real_escape_string($_POST['customer_last']) . ', 
      ' . mysql_real_escape_string($_POST['customer_address']) . ', 
      ' . mysql_real_escape_string($_POST['customer_email']) . '  )  
  ';
  mysql_query($sql);

据我所知,使用准备好的语句有一种更安全的方法。

到目前为止,我认为它是这样完成的:

$stmt = $dbh->prepare("INSERT INTO customers (customer_first, customer_last, customer_address, customer_email) VALUES (:customer_first, :customer_last, :customer_address, :customer_email)");
$stmt->bindParam(':customer_first', $_POST['customer_first']);
$stmt->bindParam(':customer_last', $_POST['customer_last']);
$stmt->bindParam(':customer_address', $_POST['customer_address']);
$stmt->bindParam(':customer_email', $_POST['customer_email']);

$stmt->execute();

这是正确的吗?还是有更好的方法来做我想要实现的目标?如果我尝试上述方法,我会收到错误“调用非对象上的成员函数 prepare()”——这是什么意思?

我正在使用示例@http://php.net/manual/en/pdo.prepared-statements.php。它指的是 $dbh - 它是从哪里得到的? $dbh 是否应该在其他地方引用 - 我假设它与数据库连接有关?

除了这些问题之外,我还可以使用 mysql_insert_id() 或 mysql_error() 之类的东西来使用上述准备好的语句吗?

【问题讨论】:

  • 除了一些依赖于应用程序的检查(强制名称不为空等)之外,它似乎还可以,就像在 SQL 注入安全中一样。请记住,您也可以放弃->bindParam() 电话,而只需拨打$dbh->execute($_POST);
  • +1 - 这样的问题再次证明了我对开发人员的信心。通常人们对他们的内联 SQL 连接非常防御。
  • 他们相当于我。仅供参考:PreparedStatements 不能帮助 IN 子句的动态参数 - 必须作为动态 SQL 完成。

标签: php mysql prepared-statement


【解决方案1】:

如果您是 OOP 新手,您可以从 mysqli 开始,以获得更直接熟悉的功能和语法以及对函数式编程的支持,但如果您准备好处理 OOP,则值得查看 PDO class。

值得回顾以帮助决定从哪里开始:mysqli or PDO - what are the pros and cons?

它指的是一个 $dbh - 它在哪里 从那里得到? $dbh 应该是 在别处引用 - 我假设它 与数据库有关 连接?

$dbh = 数据库句柄(在PDO > Connections and Connection Management 文档中定义)

我还能使用类似的东西吗 mysql_insert_id() 或 mysql_error() 使用上述准备好的语句?

PDO::lastInsertId, PDO::errorInfo

【讨论】:

  • 非常感谢您澄清这一点。
【解决方案2】:

错误消息表明您的问题出在$dbh 对象上——它是如何初始化的?

【讨论】:

  • $dbh = new PDO('mysql:host=localhost;dbname=db', $user, $pass);
  • 这是唯一的其他相关代码吗?是在这条线的正上方吗?尝试做 print_r($dbh)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-26
  • 2021-05-09
  • 1970-01-01
  • 2017-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多