有三个类:
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方法没有限制.
原先以为单例模式只是防止创建相同的对象,现在看来单例模式可以将构造函数封装起来,确实提高了安全性.
新闻热点
疑难解答