PDO 准备好的语句,正确使用了吗?

Posted

技术标签:

【中文标题】PDO 准备好的语句,正确使用了吗?【英文标题】:PDO prepared statement, correctly used? 【发布时间】: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然后***。 完全同意@Arend。我会跟进。 键不需要冒号前缀吗?如$data[':username'] = $username; 参见PDOStatement::execute() 的示例2 【参考方案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") ***.com/questions/1995562/now-function-in-php 不过,这并不能回答 为什么。我很想知道您为什么要这样做而不是信任您的 DBMS。 您想要使用 PHP 日期与存储引擎日期的唯一原因是用于时区或参考点。如果您需要从 Web 服务器所说的时间开始引用的数据,请使用它。否则,请使用NOW()。这完全取决于您想如何处理这些数据。 其实这是一个比较哲学的问题;您是否希望在代码处理数据时创建创建的“时间戳”,或者您是否希望在处理数据库事务时对其进行处理。视情况而定,但两者都是有效且正确的。

以上是关于PDO 准备好的语句,正确使用了吗?的主要内容,如果未能解决你的问题,请参考以下文章

mysql性能中的PDO

使用 PDO 准备好的语句 MySQL 错误

在 PHP 中到处使用准备好的语句? (PDO)

使用 PDO 准备好的语句插入致命错误 [重复]

PDO - 使用准备好的语句[重复]

mysql永久准备语句