首頁 >php教程 >PHP开发 >利用PHP的OOP特性實現資料保護(2)

利用PHP的OOP特性實現資料保護(2)

黄舟
黄舟原創
2016-12-21 10:59:401086瀏覽

函數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 &#39;S&#39;:
   return &#39;"&#39; . $this->db->escape_string($params[$index]) . &#39;"&#39;;
   break;
  case &#39;I&#39;:
   return (int) $params[$index];
   break;
  case &#39;N&#39;:
   return (float) $params[$index];
  default:
   throw new Exception("存储过程中指定的数据类型 &#39;$type&#39; 无法识别。");
 }
}

 函數compile()中使用了兩個額外的函數,其中compile_callback()函數是作為在preg_replace()函數呼叫中的回呼函數,每一次在query中查找到佔位符,並將它替換為傳給compile函數的值時,都會執行它。

 以上就是利用PHP的OOP特性實現資料保護(2)的內容,更多相關內容請關注PHP中文網(www.php.cn)! 


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn