当前位置: 首页 > 图文教程 > 网络编程 > PHP > 利用PHP的OOP特性实现数据保护(2)

PHP
discuz安全提问算法
PHP静态新闻列表自动生成代码
用PHP实现图象锐化代码
PHP生成月历代码
用PHP实现的随机广告显示代码
用PHP实现维护文件代码
关于在php.ini中添加extension=php_mysqli.dll指令的说明
PHP 中的批处理的实现
木翼下载系统中说明的PHP安全配置方法
php为什么选mysql作为数据库? Mysql 创建用户方法
PHP如何编写易读的代码
PHP 优化配置——加速你的VBB,phpwind,Discuz,IPB,MolyX
php下一个阿拉伯数字转中文数字的函数
Discuz5.5.0代码高亮显示+运行代码框合成插件 下载
PHP+FLASH实现上传文件进度条相关文件 下载
发布一个迷你php+AJAX聊天程序[聊天室]提供下载
在普通HTTP上安全地传输密码
php中ob(Output Buffer 输出缓冲)函数使用方法
php 用sock技术发送邮件的函数
真正的ZIP文件操作类(php)

利用PHP的OOP特性实现数据保护(2)


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-11-03   浏览: 179 ::
收藏到网摘: n/a

函数prepare

  为使用例1中的模板,你要做的第一件事是构建好prepare()函数,为确保无带引号的字符被偶然解析为占位符,函数应该移除query内所有字符串,并把它们临时存储在一个数组内。而字符串本身也会被占位符取代,其通常被识别为不应该在SQL语句中出现的的字符串序列。在query的编译期间,过程占位符会首先被替换,接着把字符串放回query中,这是通过preg_replace()函数,和另一个用作preg_replace()函数的helper回调函数完成的。

  例2:prepare()函数

/**
* 把query准备为一个存储过程。
* @param string $query Prepared query text
* @return void
*/
public function prepare($query)
{
 $this->stored_procedure = true;
 $this->quote_store = array(); //清除引号
 $this->query = preg_replace(self::$QUOTE_MATCH, '$this->sql_quote_replace("1"?"1":'2')', $query);
}

private function sql_quote_replace($match)
{
 $number = count($this->query_strings);
 $this->query_strings[] = $match;
 return "$||$$number";
}

  在此留意对静态QUOTE_MATCH属性private的使用,还有quote_store属性和sql_quote_replace()函数。相比protected,在此定义为private更能确保任何重载query类prepare()方法的子类使用其自身的机制来剔除引号。

  函数compile

  下一步是构建compile()与execute()函数。

  函数compile()如例3中所示,功能如下:

  ·接受的参数数目可变(即可变参数),其将匹配query中的占位符。

  ·检查占位符是否为正确的数据类型,并把它替换为参数中的值。

  ·把query作为字符串返回,但不执行它。

  ·如果query对象没有使用prepare()函数初始化为一个存储过程,将抛出一个异常。

  例3:compile()函数

/**
* 返回编译的query,但并不执行它。
* @param mixed $args,... Query Parameters
* @return string Compiled Query
*/
public function compile($params)
{
 if (! $this->stored_procedure) {
  throw new Exception("存储过程未被初始化!");
 }

 /* 替代参数 */
 $params = func_get_args(); // 取得函数参数
 $query = preg_replace("/(?query);

 return $this->add_strings($query); //把字符串放回query中
}

/**
* 重新插入被prepare()函数移除的字符串。
*/
private function add_strings($string)
{
 $numbers = array_keys($this->query_strings);
 $count = count($numbers);
 $searches = array();
 for($x = 0; $x < $count; $x++) {
  $searches[$x] = "$||${$numbers[$x]}";
 }

 return str_replace($searches, $this->query_strings, $string);
}

/**
* 每次执行,存储过程中都有一个占位符被替换。
*/
protected function compile_callback($params, $index, $type)
{
 --$index;

 /* 抛出一个异常 */
 if (! isset($params[$index])) {
  throw new Exception("存储过程未收到所需的参数数目!");
 }

 /* 可以在此添加别的类型,如日期和时间。 */
 switch ($type) {
  case 'S':
   return '"' . $this->db->escape_string($params[$index]) . '"';
   break;
  case 'I':
   return (int) $params[$index];
   break;
  case 'N':
   return (float) $params[$index];
  default:
   throw new Exception("存储过程中指定的数据类型 '$type' 无法识别。");
 }
}

  函数compile()中使用了两个额外的函数,其中compile_callback()函数是作为在preg_replace()函数调用中的回调函数,每一次在query中查找到占位符,并把它替换为传给compile函数的值时,都会执行它。