在建站中,注入(Injection)一直都是一个值得考虑的安全问题,在OWASP(Open Web Application Security Project) TOP 10 中位列第一。详见OWASP官网https://www.owasp.org/
当然我们要考虑的不是怎么去注入,而是怎么去防止注入(此处以php+MySQL作例)

  1. 对参数进行安全化处理。最常见的应该就是过滤了,但是过滤规则容易遗漏,就不多探讨了。其次,整数化参数应该也是一种简洁的方案。再还有一些自带的函数,例如addslashes()等。
  2. PDO预处理,也就是这篇文章的主角。安装可以查看文档https://www.php.net/manual/zh/pdo.installation.php
    PDO同时也支持其他的数据库类型,这也极大的简化了php中原有的与数据库交互的形式。
    <?php
     header("Content-Type: text/html;charset:utf-8");
     $host = 'localhost'; //数据库地址
     $port = 3306; //端口
     $user = 'root'; //用户名
     $pwd = 'root'; //密码
     $dbname = 'test'; //库名称
     $db = new PDO("mysql:dbname={$dbname};host={$host};port={$port}",$user, $pwd,array(PDO::MYSQL_ATTR_INIT_COMMAND => "set names utf8"));
    按照以上的代码,我们就实例化了一个PDO对象,最后一个参数是为了防止查询过程中乱码。
    之所以造成sql注入的原因,是因为用户恶意对我们的SQL语句进行拼接,而PDO中的prepare方法则解决了这个问题。处理数据也就是 增删改查,实例如下:
    //查
    $wd = '%'.$_GET['wd'].'%';
    $tmp = $db->prepare("SELECT * FROM `university` where `name` like ? limit 10");
    //先prepare一下我们需要执行的SQL语句,其中需要安全处理的参数是以`?`占位的
    $tmp->execute(array($wd));
    //执行prepare的execute方法,并把参数以数组方式传入
    $res = $tmp->fetchAll(PDO::FETCH_ASSOC);
    //PDO::FETCH_ASSOC参数是为了只返回对应的列的数据,如果没有这个参数的话,返回的数据会增加上以0开头排列的数据
    //fetchAll()直接返回查询到的所有数据,fetch()每次调用返回查询到的一条数据
    echo json_encode($res);//JSON化输出查询的结果
    //增删改
    $tmp = $db->prepare("UPDATE `university` SET `name`='北大' WHERE `name` = ?");
    //先prepare一下我们需要执行的SQL语句,其中需要安全处理的参数是以`?`占位的
    $tmp->execute(array("北京大学"));
    echo $tmp->rowCount();//返回影响的行数    
    ×由于上边这个实例是使用LIKE查询,所以就需要先把%包裹在参数两侧。
    当然除了安全化的这种处理,PDO也是可以执行普通的语句的。
    //查
    $sql = "SELECT * FROM `university` where `name` like '%北京%' limit 10";
    $data=$db->query($sql)->fetchAll(PDO::FETCH_ASSOC);
    echo json_encode($data);
    //增删改
    $sql = "UPDATE `university` SET `name`='北大' WHERE `name` ='北京大学'";
    $data=$db->exec($sql);//data保存的是执行SQL影响的行数
    echo $data;
    以上就是PDO的基本用法。

如有错误之处,请不吝指出。


请相信你的指尖拥有改变世界的力量。