利用PHP的OOP特性实现数据保护(2)
函数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) |
在此留意对静态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(”存储过程未被初始化!”); } /* 替代参数 */ return $this->add_strings($query); //把字符串放回query中 /** return str_replace($searches, $this->query_strings, $string); /** /* 抛出一个异常 */ /* 可以在此添加别的类型,如日期和时间。 */ |
函数compile()中使用了两个额外的函数,其中compile_callback()函数是作为在preg_replace()函数调用中的回调函数,每一次在query中查找到占位符,并把它替换为传给compile函数的值时,都会执行它。