関数 prepare
例 1 のテンプレートを使用するには、まず prepare() 関数を構築する必要があります。引用符で囲まれていない文字が誤ってプレースホルダーとして解析されることを確実にするために、関数はクエリ All 文字列を削除し、一時的にクエリを削除する必要があります。それらを配列に格納します。文字列自体もプレースホルダによって置き換えられます。プレースホルダは通常、SQL ステートメントに出現すべきではない文字列シーケンスとして認識されます。クエリのコンパイル中に、最初にプロシージャ プレースホルダが置換され、次に文字列がクエリに戻されます。これは、preg_replace() 関数と、preg_replace() 関数として使用される別のヘルパー コールバック関数によって行われます。
例 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 と比較して、ここでプライベートとして定義すると、クエリ クラスの prepare() メソッドをオーバーライドするサブクラスが独自のメカニズムを使用して引用符を削除することが保証されます。
関数compile
次のステップは、compile()関数とexecute()関数を構築することです。
関数compile()は例3に示すとおりであり、その機能は次のとおりです:
・受け入れられるパラメータの数は変数(つまり、変数パラメータ)であり、クエリ内のプレースホルダと一致します。
・プレースホルダーが正しいデータ型であるかどうかを確認し、パラメーターの値に置き換えます。
・クエリを文字列として返しますが、実行はしません。
・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()は2つの追加関数を使用しており、その中でcompile_callback()関数はpreg_replace()関数呼び出しのコールバック関数として使用されており、クエリ内で次のように検出されます。 time プレースホルダーを取得し、コンパイル関数に渡された値に置き換えます。
上記は、PHP の OOP 機能を使用してデータ保護を実現する (2) の内容です。さらに関連する内容については、PHP 中国語 Web サイト (www.php.cn) に注目してください。