【PHP】使用参数绑定防止SQL注入

本文通过一个简单的登录页面示例介绍了如何使用PHP与PDO来防止SQL注入,并展示了通过预处理方式来提升安全性。此外,还对比了使用预处理与直接执行SQL在大量数据插入时的效率差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<html>
<head>
<title>Sql注入演示</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
</head>

<body >
<form action="" method="post">
    <fieldset>
        <legend>Sql注入演示</legend>
        <table>
            <tr>
                <td>用户名:</td>
                <td><input type="text" name="username"></td>
            </tr>
            <tr>
                <td>密  码:</td>
                <td><input type="text" name="password"></td>
            </tr>
            <tr>
                <td><input type="submit" value="提交"></td>
                <td><input type="reset" value="重置"></td>
            </tr>
        </table>
    </fieldset>
</form>
</body>
</html>

<?php

    if($_POST['username']){

        try{
            $pdo = new PDO('mysql:host=localhost;dbname=mydb', 'root', 'root');
            $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        }catch(PDOException $e){
            die($e->getMessage());
        }


        try{
            /**
            * MySQL预处理和绑定
            * 当一条SQL被提交到MySQL的时候并不是立即执行,而是要先被编译为数据库可识别的指令然后再执行
            * 预处理的原理是先编译SQL,然后等待数据的传入,这样,当用户输入例如' or 1=1 #'的数据的时候
            * 该数据就仅仅作为数据被传入,而不再是SQL语句的一部分,从而达到预防注入的作用
            */
            $sql = "select * from users where user=:user and password=:password";
            $stmt = $pdo->prepare($sql);//对SQL进行预处理(编译)

            //绑定参数
            $stmt->bindParam(':user', $_POST['username']);
            $stmt->bindParam(':password', $_POST['password']);

            //执行命令
            $stmt->execute();

            if($stmt->rowCount()){
                echo "登陆成功!";  
            }else{  
                echo "您的用户名或密码输入有误,请重新登录!";  
            }

        }catch(PDOException $e){
            die($e->getMessage());
        }

    }

?>


关于预处理提升SQL效率

过去天真的以为使用PDO的预处理,因为SQL语句编译一次,相对于多条SQL语句,在连续的插入的情况下会提升效率。但在最近的试验中发现并非如此

两套复杂度相同的代码,连续插入5W条数据,在最后的执行结果并未有太大差异


 未使用预处理的代码片段

        $i=0;
        while($i < 50000){
            $user = $password = $email = mt_rand();
            $sql = "insert into users(user, password, email)values('{$user}', '{$password}', '{$email}')";
            $pdo->query($sql);
            $i++;
        }

使用预处理代码片段

        $i=0;
        $sql = "insert into users(user, password, email)values(:user, :password, :email)";
        $stmt = $pdo->prepare($sql);
        while ($i < 50000) {
            $param['user'] = $param['password'] = $param['email'] = mt_rand();
            $stmt->execute($param);
            $i++;
        }

最终执行时间对比

未使用预处理使用预处理
[root@localhost pdo]# time php test3.php 
real 0m49.901s
user 0m0.118s
sys 0m6.046s
[root@localhost pdo]# time php test4.php 
real 0m49.101s
user 0m0.140s
sys 0m6.111s






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值