【问题标题】:PDO prepared statement, correctly used?PDO 准备好的语句,正确使用了吗?
【发布时间】:2012-05-15 08:44:45
【问题描述】:

我只是需要确保我已正确获取 PDO 准备语句,以下代码是否会受到 SQL 注入的保护?

$data['username'] = $username;
$data['password'] = $password;
$data['salt'] = $this->generate_salt();
$data['email'] = $email;

$sth = $this->db->prepare("INSERT INTO `user` (username, password, salt, email, created) VALUES (:username, :password, :salt, :email, NOW())");  
$sth->execute($data);

【问题讨论】:

  • 看起来不错。通过这种方式可以防止 SQL 注入。这个问题更多的是codereview然后stackoverflow。
  • 完全同意@Arend。我会跟进。
  • 键不需要冒号前缀吗?如$data[':username'] = $username; 参见PDOStatement::execute() 的示例2

标签: php pdo


【解决方案1】:

是的,您的代码是安全的。但是可以缩短:

$data = array( $username, $password, $this->generate_salt(), $email );

// If you don't want to do anything with the returned value:
$this->db->prepare("
    INSERT INTO `user` (username, password, salt, email, created)
    VALUES (?, ?, ?, ?, NOW())
")->execute($data);

【讨论】:

  • 如果您希望它更短,您可以像$sth = $this->db->prepare("INSERT INTO user (username,password,salt,email,created) VALUES (?, ?, ?, ?, NOW()")->execute($data); 一样将执行链接到其中:)
  • 非常感谢。实际上,我总是倾向于链接很多代码以使其简短。 :)
  • 命名变量没问题!你为什么要摆脱他们?除了琐碎的语句之外,我觉得它们在调试时非常有用,并且还允许您在查询中需要时多次使用命名参数。
  • 这只是为了表明这是可能的。每个都有其优点和缺点:)
  • 更短! $this->db->prepare(" INSERT INTO user (username, password, salt, email, created) VALUES (?, ?, ?, ?, NOW()) ")->execute(array($username, $password, $this->generate_salt(), $email));
【解决方案2】:

您可以从$data 之类的空数组开始

// start with an fresh array for data
$data = array();

// imagine your code here

到目前为止,您的代码看起来不错。

编辑:我错过了您的 NOW() 电话。恕我直言,您也应该使用绑定变量添加它,例如

// bind date
$data['created'] = date("Y-m-d H:i:s");

// updated prepare statement
$sth = $this->db->prepare("INSERT INTO `user` (username, password, salt, email, created) VALUES (:username, :password, :salt, :email, :created)");

【讨论】:

  • NOW() 不是 PHP 函数,因此这会引发错误。如果你真的想使用 PHP 服务器的时间戳而不是数据库服务器,你应该使用 date("Y-m-d H:i:s") stackoverflow.com/questions/1995562/now-function-in-php
  • 不过,这并不能回答 为什么。我很想知道您为什么要这样做而不是信任您的 DBMS。
  • 您想要使用 PHP 日期与存储引擎日期的唯一原因是用于时区或参考点。如果您需要从 Web 服务器所说的时间开始引用的数据,请使用它。否则,请使用NOW()。这完全取决于您想如何处理这些数据。
  • 其实这是一个比较哲学的问题;您是否希望在代码处理数据时创建创建的“时间戳”,或者您是否希望在处理数据库事务时对其进行处理。视情况而定,但两者都是有效且正确的。
猜你喜欢
  • 2016-12-30
  • 1970-01-01
  • 2017-09-29
  • 2010-11-30
  • 1970-01-01
  • 2013-10-26
相关资源
最近更新 更多