有三個類:
1,過濾輸入,輕量級的 class input_filter,負責將參數,如$_GET,$_POST 這些過濾,返回值類型為 數組,用作 made_sql 類的參數.
2,轉換成SQL語句 class made_sql,參數的類型為數組和表名(字符串),數組的鍵名為表的列名,值為插入值.返回值類型為 字符串,用作 mysql ->query方法的參數.
3,數據庫查詢 class mysql 用到了單列模式,用靜態方法來獲取對象,具體參看 instanceof操作符的作用.
1,過濾輸入 class input_filter 類代碼如下:
- class input_filter
- {
- private $input_all; // 要過濾的數組
- private $rustle; // 過濾后的結果
- //構造函數 參數可以是$_GET or $_POST 這些
- public function __construct($input_C)
- {
- if(is_array($input_C))
- $this->input_all = $input_C ;
- else
- echo 'Parameter is not valid';
- //初始化,不然后面第一次合并數組PHP不知道這是什么類型
- $this->rustle = array();
- }
- private function filter_arr() // 主函數
- {
- foreach ($this->input_all as $key_input => $val_input)
- {
- //如果鍵名不是字符串,那么返回錯誤信息
- // for key
- if(!is_string($key_input)) // error
- {
- echo 'This key is not string';
- return false;
- }
- // The # is mysql Note .
- $key_one = str_replace('#','',$key_input);
- $key = htmlspecialchars($key_one,ENT_QUOTES,'UTF-8');
- // 我沒找 # 的HTML轉義符,所以用空代替
- $val_one = str_replace('#','',$val_input);
- // 這個函數只轉化 < > ' " ,還有個類似函數會轉義所有符號
- $val = htmlspecialchars($val_one,ENT_QUOTES,'UTF-8');
- // merger
- $rustle_one = array($key=>$val);
- //合并數組
- $this->rustle = array_merge($this->rustle,$rustle_one);
- }
- }
- //這個函數有點多余,留下以后擴展用
- public function get_filter_rustle()
- {//開源代碼Vevb.com
- $this->filter_arr();
- return $this->rustle ;
- }
- }
- 調用方法:
- $filter = new filter_input($_GET) ; // or $_POST
- $input_data = $filter->get_filter();
2,轉換成SQL語句,class madesql類代碼如下:
- class madesql
- {
- private $Cnow_ary; // type array 傳入的參數
- private $Cname_str;
- private $insert_sql; //最終的sql語句 string type
- public function __construct($Cary,$Cname)
- {
- //檢查傳入參數類型是否為數組
- if (! is_array($Cary))
- return false;
- else
- $this->Cnow_ary = $Cary; // 寫入的值
- $this->Cname_str = $Cname; // 數據庫表名稱
- }
- private function setSql() // 主函數 ,生產SQL語句
- {
- foreach ( $this->Cnow_ary as $key_ary => $val_ary )
- {
- $cols_sql = $cols_sql.','.$key_ary; //列名組合
- $vals_sql = $vals_sql.', ''.$val_ary.''' ; //值 組合
- }
- // 因為前面foreach的算法有點問題,第一個字符是逗號
- // 所以用sunstr_replace()刪除 ,自第一位起(0),只替換一個字符(1)
- $cols_sql = substr_replace($vals_sql,'',0,1);
- $vals_sql = substr_replace($vals_sql,'',0,1);
- $this->insert_sql =
- 'INSERT INTO '.$this->Cname_str.' ( '
- .$cols_sql.' ) VALUES ( '.$vals_sql.' )'; // 語句成型
- }
- //擴展用
- public function getSql()
- {
- $this->setSql();
- return $this->insert_sql;
- }
- }
3,數據庫查詢,mysql類代碼如下:
數據庫查詢類是參照書上的單列模式,用靜態方法獲取對象,這樣在一個腳本里只有一個數據庫查詢類的實例.我想單例模式用于這個類還是有點用的.
- class mysql
- {
- private $connect;
- static $objectMysql; // 存放對象
- private function __construct()
- {
- // 創建對象的時候這個構造函數會被調用,用來初始化
- $connect = mysql_connect('db address','password','dbname');
- $this->db = mysql_select_db('db',$connect);
- }
- public static function Mysql_object()
- {
- //instanceof 操作符用于檢查對象是否屬于某個類或者接口的實例。我說的不是很規范...
- //如果$objectMysql不是mysql(self)的實例,那么就創建一個
- if(! self::$objectMysql instanceof self)
- self::$objectMysql = new mysql();
- //這時候的$objectMysql就已經是一個對象
- return self::$objectMysql;
- }
- public function query($sql)
- {
- return mysql_query($sql,$this->db);
- }
- }
歸納一下使用方法:
- $filter = new filter_input($_GET) ; // or $_POST http://www.111cn.net
- $input_data = $filter->get_filter();
- $madeSql = new madesql($input_data,'tableName');
- $sql = $madeSql->getSql();
- $mysql = mysql::Mysql_object() ;
- if( $mysql->query($sql) )
- echo 'Ok';
- lse
- echo 'failure';
只需要這幾行調用代碼即可以完成寫入數據庫的操作.
另外再說一下構造函數的私有公有問題,書上的mysql單例模式中構造函數是聲明為了private,而沒有單例模式的類如此則會產生編譯錯誤,即 PHP 不能創建一個對象,查了下.
原因在于創建對象往往在類外面進行,這樣就產生了無法訪問構造函數的問題,而單列模式是在自身類中創建對象,因此訪問private方法沒有限制.
原先以為單例模式只是防止創建相同的對象,現在看來單例模式可以將構造函數封裝起來,確實提高了安全性.
新聞熱點
疑難解答