php数据库写入操作类

有三个类:

1,过滤输入,轻量级的 class input_filter,负责将参数,如$_GET,$_POST 这些过滤,返回值类型为 数组,用作 made_sql 类的参数.

2,转换成SQL语句 class made_sql,参数的类型为数组和表名(字符串),数组的键名为表的列名,值为插入值.返回值类型为 字符串,用作 mysql ->query方法的参数.

3,数据库查询 class mysql 用到了单列模式,用静态方法来获取对象,具体参看 instanceof操作符的作用.

1,过滤输入 class input_filter 类代码如下:

  1. class input_filter
  2. {
  3. private $input_all; // 要过滤的数组
  4. private $rustle; // 过滤后的结果
  5. //构造函数 参数可以是$_GET or $_POST 这些
  6. public function __construct($input_C)
  7. {
  8. if(is_array($input_C))
  9. $this->input_all = $input_C ;
  10. else
  11. echo 'Parameter is not valid';
  12. //初始化,不然后面第一次合并数组PHP不知道这是什么类型
  13. $this->rustle = array();
  14. }
  15. private function filter_arr() // 主函数
  16. {
  17. foreach ($this->input_all as $key_input => $val_input)
  18. {
  19. //如果键名不是字符串,那么返回错误信息
  20. // for key
  21. if(!is_string($key_input)) // error
  22. {
  23. echo 'This key is not string';
  24. return false;
  25. }
  26. // The # is mysql Note .
  27. $key_one = str_replace('#','',$key_input);
  28. $key = htmlspecialchars($key_one,ENT_QUOTES,'UTF-8');
  29. // 我没找 # 的HTML转义符,所以用空代替
  30. $val_one = str_replace('#','',$val_input);
  31. // 这个函数只转化 < > ' " ,还有个类似函数会转义所有符号
  32. $val = htmlspecialchars($val_one,ENT_QUOTES,'UTF-8');
  33. // merger
  34. $rustle_one = array($key=>$val);
  35. //合并数组
  36. $this->rustle = array_merge($this->rustle,$rustle_one);
  37. }
  38. }
  39. //这个函数有点多余,留下以后扩展用
  40. public function get_filter_rustle()
  41. {//开源代码phpfensi.com
  42. $this->filter_arr();
  43. return $this->rustle ;
  44. }
  45. }
  46. 调用方法:
  47. $filter = new filter_input($_GET) ; // or $_POST
  48. $input_data = $filter->get_filter();

2,转换成SQL语句,class madesql类代码如下:

  1. class madesql
  2. {
  3. private $Cnow_ary; // type array 传入的参数
  4. private $Cname_str;
  5. private $insert_sql; //最终的sql语句 string type
  6. public function __construct($Cary,$Cname)
  7. {
  8. //检查传入参数类型是否为数组
  9. if (! is_array($Cary))
  10. return false;
  11. else
  12. $this->Cnow_ary = $Cary; // 写入的值
  13. $this->Cname_str = $Cname; // 数据库表名称
  14. }
  15. private function setSql() // 主函数 ,生产SQL语句
  16. {
  17. foreach ( $this->Cnow_ary as $key_ary => $val_ary )
  18. {
  19. $cols_sql = $cols_sql.','.$key_ary; //列名组合
  20. $vals_sql = $vals_sql.', ''.$val_ary.''' ; //值 组合
  21. }
  22. // 因为前面foreach的算法有点问题,第一个字符是逗号
  23. // 所以用sunstr_replace()删除 ,自第一位起(0),只替换一个字符(1)
  24. $cols_sql = substr_replace($vals_sql,'',0,1);
  25. $vals_sql = substr_replace($vals_sql,'',0,1);
  26. $this->insert_sql =
  27. 'INSERT INTO '.$this->Cname_str.' ( '
  28. .$cols_sql.' ) VALUES ( '.$vals_sql.' )'; // 语句成型
  29. }
  30. //扩展用
  31. public function getSql()
  32. {
  33. $this->setSql();
  34. return $this->insert_sql;
  35. }
  36. }

3,数据库查询,mysql类代码如下:

数据库查询类是参照书上的单列模式,用静态方法获取对象,这样在一个脚本里只有一个数据库查询类的实例.我想单例模式用于这个类还是有点用的.

  1. class mysql
  2. {
  3. private $connect;
  4. static $objectMysql; // 存放对象
  5. private function __construct()
  6. {
  7. // 创建对象的时候这个构造函数会被调用,用来初始化
  8. $connect = mysql_connect('db address','password','dbname');
  9. $this->db = mysql_select_db('db',$connect);
  10. }
  11. public static function Mysql_object()
  12. {
  13. //instanceof 操作符用于检查对象是否属于某个类或者接口的实例。我说的不是很规范...
  14. //如果$objectMysql不是mysql(self)的实例,那么就创建一个
  15. if(! self::$objectMysql instanceof self)
  16. self::$objectMysql = new mysql();
  17. //这时候的$objectMysql就已经是一个对象
  18. return self::$objectMysql;
  19. }
  20. public function query($sql)
  21. {
  22. return mysql_query($sql,$this->db);
  23. }
  24. }

归纳一下使用方法:

  1. $filter = new filter_input($_GET) ; // or $_POST http://www.111cn.net
  2. $input_data = $filter->get_filter();
  3. $madeSql = new madesql($input_data,'tableName');
  4. $sql = $madeSql->getSql();
  5. $mysql = mysql::Mysql_object() ;
  6. if( $mysql->query($sql) )
  7. echo 'Ok';
  8. lse
  9. echo 'failure';

只需要这几行调用代码即可以完成写入数据库的操作.

另外再说一下构造函数的私有公有问题,书上的mysql单例模式中构造函数是声明为了private,而没有单例模式的类如此则会产生编译错误,即 PHP 不能创建一个对象,查了下.

原因在于创建对象往往在类外面进行,这样就产生了无法访问构造函数的问题,而单列模式是在自身类中创建对象,因此访问private方法没有限制.

原先以为单例模式只是防止创建相同的对象,现在看来单例模式可以将构造函数封装起来,确实提高了安全性.