| 网站首页 | 业界新闻 | 技术文章 | 视频教程 | 下载频道 | 程序源码 | 个人空间 | 编程论坛 |
 
| 技术教程首页 | 开发语言 | WEB开发 | .NET技术 | 数据库 | 操作系统 | 网页制作 |
 
 
您现在的位置: 编程中国 >> 技术教程 >> Web开发 >> PHP >> PHP技术资料 >> 正文
  ►  在PHP中全面阻止SQL注入式攻击之三
在PHP中全面阻止SQL注入式攻击之三
作者:朱先忠编译    阅读人次:……    文章来源:天极开发    发布时间:2007-8-22    网友评论()条
 

  三、 保护一个新的应用程序

  如果你正在创建一个新的应用程序,那么,你可以从头开始创建一个安全抽象层。如今,PHP 5新改进的对于MySQL的支持(这主要体现在新的mysqli扩展中)为这种安全特征提供了强有力的支持(既有过程性的,也有面向对象特征的)。你可以从站点http://php.net/mysqli上获取有关mysqli的信息。注意,只有当你使用--with-mysqli=path/to/mysql_config选项编译PHP时,这种mysqli支持才可用。下面是该代码的一个过程性版本,用于保护一个基于mysqli的查询:

<?php
 //检索用户的输入
 $animalName = $_POST['animalName'];
 //连接到数据库
 $connect = mysqli_connect( 'localhost', 'username', 'password', 'database' );
 if ( !$connect ) exit( 'connection failed: ' . mysqli_connect_error() );
 //创建一个查询语句源
 $stmt = mysqli_prepare( $connect,"SELECT intelligence FROM animals WHERE name = ?" );
 if ( $stmt ) {
  //把替代绑定到语句上
  mysqli_stmt_bind_param( $stmt, "s", $animalName );
  //执行该语句
  mysqli_stmt_execute( $stmt );
  //检索结果...
  mysqli_stmt_bind_result( $stmt, $intelligence );
  // ...并显示它
  if ( mysqli_stmt_fetch( $stmt ) ) {
   print "A $animalName has $intelligence intelligence.\n";
  } else {
   print 'Sorry, no records found.';
  }
  //清除语句源
  mysqli_stmt_close( $stmt );
 }
 mysqli_close( $connect );
?>

  该mysqli扩展提供了一组函数用于构造和执行查询。而且,它也非常准确地提供了前面使用我们自己的safe()函数所实现的功能。

  在上面的片断中,首先收集用户提交的输入内容并建立数据库连接。然后,使用mysqli_prepare()函数创建一个查询语句源-在此命名为$stmt以反映使用它的函数的名称。这个函数使用了两个参数:连接资源和一个字符串(每当你使用扩展插入一个值时,"?"标记被插入到其中)。在本例中,你仅有一个这样的值-动物的名字。

  注意,在一个SELECT语句中,放置"?"标记的唯一的有效位置是在值比较部分。这正是为什么你不需要指定使用哪个变量的原因(除了在mysqli_stmt_bind_param()函数中之外)。在此,你还需要指定它的类型-在本例中,"s"代表字符串。其它可能的类型有:"I"代表整数,"d"代表双精度数(或浮点数),而"b"代表二进制字符串。

  函数mysqli_stmt_execute(),mysqli_stmt_bind_result()和mysqli_stmt_fetch()负责执行查询并检索结果。如果存在检索结果,则显示它们;如果不存在结果,则显示一条无害的消息。最后,你需要关闭$stmt资源以及数据库连接-从内存中对它们加以释放。

  假定一个合法的用户输入了字符串"lemming",那么这个例程将(假定是数据库中适当的数据)输出消息"A lemming has very low intelligence."。假定存在一个尝试性注入-例如"lemming' or 1=1;",那么这个例程将打印(无害)消息"Sorry, no records found."。
此外,mysqli扩展还提供了一个面向对象版本的相同的例程。下面,我们想说明这种版本的使用方法。

<?php
 $animalName = $_POST['animalName'];
 $mysqli = new mysqli( 'localhost', 'username', 'password', 'database');
 if ( !$mysqli ) exit( 'connection failed: ' . mysqli_connect_error() );
 $stmt = $mysqli->prepare( "SELECT intelligence
 FROM animals WHERE name = ?" );
 if ( $stmt ) {
  $stmt->bind_param( "s", $animalName );
  $stmt->execute();
  $stmt->bind_result( $intelligence );
  if ( $stmt->fetch() ) {
   print "A $animalName has $intelligence intelligence.\n";
  } else {
   print 'Sorry, no records found.';
  }
  $stmt->close();
 }
 $mysqli->close();
?>

  实际上,这部分代码是前面描述代码的复制-它使用了一种面向对象的语法和组织方法,而不是严格的过程式代码。

上一页  [1] [2] [3] 下一页

 

 
文章录入:编辑01    责任编辑:编辑01 
  • 上一篇文章:

  • 下一篇文章:

  •  
    相关文章
    原创地带
    24小时热门帖子