比如:  $link = new Mysqli('localhost', 'root', '111111', 'test');
  $link -> set_charset('utf8');  $sql = 'SELECT * FROM test WHERE id=? AND name=?';
  $stmt = $link -> prepare($sql);
  $stmt -> bind_param('is', $id, $name);
  $stmt -> execute();
就上面这个例子来说,我的理解是:
Mysql在真正执行前,就已经定死了SQL语句中“?”号所代表的类型值。
所以,如果给id位置处的“?”传字符串值,它也会转成整型,这样就防止了SQL注入。但是,name处的“?”,本来传递的就应该是字符串,那如果要是传给它一个SQL注入的语句,还怎么防止SQL注入呢?不知道我的理解对不对,请大家指教!谢谢!!

解决方案 »

  1.   

    prepare预处理的实现过程其实就是内部转义的过程,将一些需要转义的字符进行转义,你是看不见的,就如同你自己封装了一个转义方法相似,如果不预处理而是直接执行,那么是没有转义这一步骤的,因此增加了危险系数
      

  2.   

    是像楼上是的用个addslashes(),或者mysql_escape_string()吗?
      

  3.   

    差不多,具体什么样子那需要看php的源码,不过道理都是一个样的
      

  4.   

    养成习惯,不懂的问题问php.net,实在找不到再来问论坛。结论就是你不用addslashes,你的sql语句里的?也不用''包围,prepare全自动的'addlashes()'。
      

  5.   

    $v = ( is_int( $v ) ? $v : "'".pg_escape_string( $v )."'" );
    LZ跟我用的是一样的 都是用?占位符方式。? 跟值一一对应,在查询之前依次替换,这个时候 整形的 用is_int  ,字符串就用 pg_escape_string()
    pg_escape_string() 转义 text/char 数据类型的字符串,返回转义后的字符串。建议用此函数替代 addslashes()。(我用pgsql数据库)进行转义。$real_sql .= preg_replace('/\?/', $v, $sql_arr[$key],1); 这是?的替换。
      

  6.   

    mysql_escape_string  用这个接受用户 或者自己写个过虑用户传来的值基本就可以防止sql注入了