【发布时间】:2017-09-13 11:38:03
【问题描述】:
我对 PHP 中的 Prepared Statements 有点困惑,我一直在 youtube 上观看以下教程:https://www.youtube.com/watch?v=aN5KqxK1slc
在我收到以下关于我当前 Mysqli 源代码的说明后:
您对 SQL 注入非常开放,应该真正使用 Prepared 语句而不是连接您的查询。特别是因为 你根本没有逃避用户输入!
我的问题:
我将如何准备语句,因为我在 register 类 中为语句创建语法,并且只将语句传递给我的 database 类 以使用它执行它execute_query 函数?
我是否只需准备 execute_query 函数中的语句并检查它是格式为 INSERT 还是 SELECT 的语句,然后准备值?
感谢任何形式的建议和反馈。
我当前的代码如下所示:
注册类:
<?php
class register extends database
{
function __construct($username, $password, $email)
{
$this->username = $username;
$this->password = password_hash($password, PASSWORD_DEFAULT);
$this->email = $email;
$this->activation_id = $this->generateActivationId();
$this->sender_email = 'support@url.com';
$this->activation_link = 'http://url.com/folder/activate.php?id=' . $this->activation_id;
$this->database = new database();
}
function generateActivationId()
{
$generator = bin2hex(random_bytes(10));
return $generator;
}
function registerAccount()
{
$this->database->connect();
$user_lookup = $this->database->execute_query("SELECT * FROM users WHERE username = '" . $this->username . "'");
if (mysqli_num_rows($user_lookup) > 0)
{
return false;
}
else
{
$this->database->execute_query("INSERT INTO users (username, password, email, activation_id) VALUES ('" . $this->username . "', '" . $this->password . "', '" . $this->email . "', '" . $this->activation_id . "')");
$user_lookup_comfirm = $this->database->execute_query("SELECT * FROM users WHERE username = '" . $this->username . "'");
if (mysqli_num_rows($user_lookup_comfirm) > 0)
{
$this->sendRegisterEmail();
return true;
}
else
{
return false;
}
}
}
function sendRegisterEmail()
{
$subject = 'Registration - Activate your account';
$message = 'Thank you for registering. Please activate your account by visiting the following site: <a href="' . $this->activation_link . '">Website link</a>';
$headers = 'From: ' . $this->sender_email . "\r\n" .
'Reply-To: ' . $this->sender_email . "\r\n" .
'X-Mailer: PHP/' . phpversion();
mail($this->email, $subject, $message, $headers);
}
}
?>
数据库类:
<?php
class database
{
function __construct()
{
$this->dBusername = 'xxx';
$this->dBpassword = 'xxx';
$this->dBhost = 'localhost';
$this->dBdatabase = 'xxx';
$this->dBcharset = 'utf8';
}
function connect()
{
$mysqli = new mysqli($this->dBhost, $this->dBusername, $this->dBpassword, $this->dBdatabase);
if ($mysqli->connect_errno)
{
$this->_mysqli = false;
}
else
{
$mysqli->set_charset($this->charset);
$this->_mysqli = $mysqli;
}
}
function execute_query($sql)
{
if($results = $this->_mysqli->query($sql))
{
return $results;
}
else
{
return false;
}
}
}
?>
【问题讨论】:
-
database类什么都不做。摆脱它,直接使用mysqli或PDO实例。 -
所以我应该创建一个完整的数据库处理程序类来创建一个 mysqli 实例,然后在那里准备语句并从注册类调用这些函数?
-
您应该直接使用 MySQLi 或 PDO 接口。您不需要包装器,在大多数情况下,它最终会导致比它解决的问题更令人头疼的问题。
-
所以应该这样做:pastebin.com/uPptjRep 我只会调用其他类的函数对吗?
-
将每次出现的
$this->database->...替换为$this->mysqli->...。现在清除吗?