0

我有以下 PHP 函数:

公共函数注册(){
        $mysql = mysqli_connect(主机名,用户名,密码,数据库);
        if (mysqli_connect_errno($mysql)) {
            $this->viewModel->set("pageTitle", "Signup");
            $this->viewModel->set("message", "连接服务器时出错。");
            返回 $this->viewModel;
        }
        if ($result = $mysql->query("SELECT id FROM mailinglist WHERE email='" . $this->email . "';")) {
            if ($result->num_rows == 0) {
                $mysql->query("INSERT INTO mailinglist (email) VALUES ('" . $this->email . "');");
                $this->viewModel->set("message", "太好了!感谢您注册" . $this->email . ".");
            } 别的 {
                $this->viewModel->set("message", "你已经注册了更新!");
            }
        } 别的 {
            $this->viewModel->set("message", "添加邮件列表时出错。");
        }
        $this->viewModel->set("pageTitle", "Signup");
        返回 $this->viewModel;
    }

哪个运行良好并且完全返回我想要的,但是,如果我尝试使用 mysqli_real_escape_string() 来查询,它就不起作用。也就是下面的代码

公共函数注册(){
        $mysql = mysqli_connect(主机名,用户名,密码,数据库);
        if (mysqli_connect_errno($mysql)) {
            $this->viewModel->set("pageTitle", "Signup");
            $this->viewModel->set("message", "连接服务器时出错。");
            返回 $this->viewModel;
        }
        $query = $mysql->real_escape_string("SELECT id FROM mailinglist WHERE email='" . $this->email . "';");
        if ($result = $mysql->query($query)) {
            if ($result->num_rows == 0) {
                $query = $mysql->real_escape_string("INSERT INTO mailinglist (email) VALUES ('" . $this->email . "');");
                $mysql->查询($查询);
                $this->viewModel->set("message", "太好了!感谢您注册" . $this->email . ".");
            } 别的 {
                $this->viewModel->set("message", "你已经注册了更新!");
            }
        } 别的 {
            $this->viewModel->set("message", "添加邮件列表时出错。");
        }
        $this->viewModel->set("pageTitle", "Signup");
        返回 $this->viewModel;
    }

不起作用。连接不是问题,我尝试使用 mysqli_real_escape_string() 而不是 $mysql->real_escape_string() 但它们都不起作用。谁能看到这段代码有什么问题?

4

2 回答 2

2

不要这样做,使用准备好的语句。它们更安全、更可靠。您仍然需要清理数据以获得适当的价值和跨站点脚本,以列出您仍然会遇到的一些风险。转义数据是防止 SQL 注入的一种方法,但它并不是完全的证明。准备好的语句告诉数据库服务器假设传入的数据是不安全的,只是接受它,不要像连接字符串一样处理它。数据库接受您的参数,就像它们是语句的变量而不是语句的一部分一样。

以下是如何将您的声明更改为准备好的声明:

$stmt=$mysql->prepare("SELECT id FROM mailinglist WHERE email=?");
$stmt->bind_param('s',$this->email);
$result=$stmt->execute();
if ($result) {
    if ($result->num_rows == 0) {
        $stmt=$mysql->prepare("INSERT INTO mailinglist (email) VALUES (?)");
        $stmt->bind_param('s', $this->email);
        $stmt->execute();
        $this->viewModel->set("message", "Great! Thanks for signing up " . $this->email . ".");
     } else {
        $this->viewModel->set("message", "You are already signed up for updates!");
     }
} else {
     $this->viewModel->set("message", "There was an error adding you the mailing list.");

}
于 2013-11-05T04:31:30.527 回答
-1

您必须转义数据而不是整个查询。

public function signup() {
        $mysql = mysqli_connect(HOSTNAME, USERNAME, PASSWORD, DATABASE);
        if (mysqli_connect_errno($mysql)) {
            $this->viewModel->set("pageTitle", "Signup");
            $this->viewModel->set("message", "There was an error connecting to the server.");
            return $this->viewModel;
        }
       $query = "SELECT id FROM mailinglist WHERE email='" .$mysql->real_escape_string( $this->email ). "'"
        if ($result = $mysql->query($query)) {
            if ($result->num_rows == 0) {
               $query = "INSERT INTO mailinglist (email) VALUES ('" . $mysql->real_escape_string($this->email) . "')";
                $mysql->query($query);
                $this->viewModel->set("message", "Great! Thanks for signing up " . $this->email . ".");
            } else {
                $this->viewModel->set("message", "You are already signed up for updates!");
            }
        } else {
            $this->viewModel->set("message", "There was an error adding you the mailing list.");
        }
        $this->viewModel->set("pageTitle", "Signup");
        return $this->viewModel;
    }
于 2013-11-05T04:01:30.033 回答