好长时间没有写博客了,这段时间过得紧张的不行,以致于都没有抽出时间来好好的总结一下自己这段时间的生活和学习。
其实今天不想写什么技术博客,就想简单总结一下这段时间的生活。10月8号从家里回来以后决定自己搭建一个小的MVC框架,并且用这个框架去实现自己博客网站的编写。紧紧张张的忙活了不到20天吧,终于是大致把这个东西完成了,现在就差部署到Linux的服务器上了。唉,有件事我也是醉了,当初在windows下写的,结果部署到Linux上以后路径都不认了,我还要重新改代码里的路径,又要费一番功夫。
既然都已经写了,还是写点自己这段时间小项目的总结吧。
PHP搭建自己的mvc框架,先说一下什么是MVC吧,个人认为MVC就是一种编程的时候的一种编程思想,或者是一种编程模式,这种模式要求我们在编写程序代码时,将整个项目分为三层,分别是视图(View)、控制器(Controller)和模型(Model),通过这种编程模式做到将程序业务处理和数据显示相分离。视图(View)用于处理数据显示,控制器(Controller)负责向视图层写入数据显示和获取视图层数据传给Model层处理(个人认为就是一个中间层,不一定准确...)。模型(Model)主要和数据打交道,用于数据的存取和业务逻辑的处理。既然清楚了MVC模式的原理,接下来就可以根据原理编写自己的框架了。
先说一下,我自己的框架的DB引擎就是自己搭建的了,视图引擎采用的是Smarty模板引擎,这也是当下很好的做到将php逻辑代码和页面HTML代码分离的模板。
接着说框架,既然是一个框架,当然这个框架就要有对数据库的处理和对视图的处理。所以,我们应该封装一个对数据库进行操作的数据库操作类mysql.class.php
1 <?php 2 /* 3 本部分主要是对mysql数据库操作的一些列封装 4 */ 5 class mysql{ 6 /* 7 报错函数 8 参数:$error 9 */ 10 function err($error){ 11 die("对不起,您的操作有误,错误原因为:".$error); //die()函数有两种作用:输出和终止,相当于echo和exit的组合 12 } 13 14 /* 15 数据库连接方法 16 参数:连接配置的一个数组 17 */ 18 function connect($config){ 19 if(!$con=mysql_connect($config["dbHost"],$config["dbUser"],$config["dbPwd"])){ 20 $this->err(mysql_error()); 21 } 22 if(!mysql_select_db($config["dbName"],$con)){ 23 $this->err(mysql_error()); 24 } 25 mysql_query("set names ".$config["dbCharset"]); 26 } 27 28 /* 29 数据库查询方法 30 参数:sql语句$sql 31 返回:查询获得的资源 32 */ 33 function query($sql){ 34 $query=mysql_query($sql); 35 if(!$query){ 36 $this->err(mysql_error()); 37 } 38 else{ 39 return $query; 40 } 41 } 42 43 /* 44 获取全部信息的方法 45 参数:$query——执行sql语句后查询获得的资源 46 */ 47 function fetchAll($query){ 48 while($rs=mysql_fetch_array($query,MYSQL_ASSOC)){ 49 $list[]=$rs; 50 } 51 return isset($list)?$list:""; 52 } 53 54 /* 55 获取一条数据的方法 56 参数:$query——执行sql语句后查询获得的资源 57 */ 58 function fetchOne($query){ 59 $rs=mysql_fetch_array($query,MYSQL_ASSOC); 60 return $rs; 61 } 62 63 /* 64 insert into table (a,b,c) values(av,bv,cv) 65 数据插入方法: 66 参数:$table——要插入数据的表名 67 $arr——要插入的数据 68 */ 69 function insert($table,$arr){ 70 foreach($arr as $key=>$val){ 71 $value=mysql_real_escape_string($val); 72 $keyArr[]=$key; 73 $valArr[]="'".$value."'"; 74 } 75 $keyStr=implode(",",$keyArr); //将对应参数转换为字符串 76 $valStr=implode(",",$valArr); 77 $sql = "insert into ".$table."(".$keyStr.") values(".$valStr.")"; 78 $this->query($sql); 79 return mysql_insert_id(); //mysql_insert_id()返回上一步insert语句产生的id 80 } 81 82 /* 83 update table set a=av,b=bv,c=cv where ... 84 参数:$table——被更新数据所在表名 85 $arr——更新后的数据 86 $where——update语句的条件 87 */ 88 function update($table,$arr,$where){ 89 foreach($arr as $key=>$val){ 90 $value=mysql_real_escape_string($val); 91 $keyToVal[]=$key."='".$val."'"; 92 } 93 $keyToValStr=implode(",",$keyToVal); 94 $sql="update $table set ".$keyToValStr." where $where"; 95 $this->query($sql); 96 return mysql_affected_rows(); 97 } 98 99 /* 100 delete from table where ... 101 */ 102 function del($table,$where){ 103 $sql="delete from $table where $where"; 104 $this->query($sql); 105 } 106 107 /** 108 *指定行的指定字段的值 109 * 110 *@param source $query sql语句通过mysql_query执行出的来的资源 111 *return array 返回指定行的指定字段的值 112 **/ 113 function findResult($query, $row = 0, $filed = 0){ 114 $rs = mysql_result($query, $row, $filed); 115 return $rs; 116 } 117 }
以上代码就涉及到了对数据库的基本处理,包括对增删改查等基本操作。
在封装完上述mysql.class.php的操作类之后,我们还应该封装一个用于数据库的DB引擎类,这个类用于直接和我们的sql语句打交道。为了方便使用,我们在这里就将其中的方法封装成静态方法,不用于去实例化,可以直接操作。
1 <?php 2 /* 3 数据库引擎的工厂类 4 */ 5 class DB{ 6 public static $db; //用于存放初始化的数据库操作类的对象 7 public static $mem; //用于存放初始化的缓存操作类的对象 8 9 /* 10 初始化: 11 用于初始化数据库操作类对象和连接数据库 12 */ 13 public static function init($dbType,$config){ 14 self::$db=new $dbType; 15 self::$db->connect($config); 16 17 self::$mem=new Mem_Cache($config); 18 self::$mem->mConnect(); 19 } 20 21 /* 22 执行sql语句的方法 23 成功则返回查询后的资源信息 24 否则返回错误信息 25 */ 26 public static function query($sql){ 27 return self::$db->query($sql); 28 } 29 30 /* 31 查看缓存服务器中是否存在数据的方法 32 若存在则返回1;若不存在则返回0 33 */ 34 public static function m_is_exit($key){ 35 $is_exit=self::$mem->mGet($key); 36 if($is_exit==0){ 37 return 0; //0表示当前缓存服务器不存在$key的缓存数据 38 } 39 else{ 40 return 1; //1表示当前缓存服务器存在$key的缓存数据 41 } 42 } 43 44 /* 45 将传入的sql语句md5加密 46 */ 47 public function getKeyBySql($sql){ 48 return md5($sql); 49 } 50 51 /* 52 获取多条数据的方法 53 成功则返回多条数据的数组 54 否则返回错误信息 55 */ 56 public static function fetchAll($sql){ 57 //$query=self::query($sql); 58 //return self::$db->fetchAll($query); 59 60 $key=md5($sql); //获取要执行的sql语句的md5加密后的$key 61 $is_exit=self::m_is_exit($key); 62 if($is_exit==0){ //当前不存在$key的缓存 63 $query=self::query($sql); 64 $data=self::$db->fetchAll($query); 65 self::$mem->mSet($key,$data); 66 return $data; 67 } 68 else{ 69 //当前缓存中存在,则从缓存中获取数据 70 return self::$mem->mGet($key); 71 } 72 } 73 74 /* 75 获取一条数据的方法 76 成功则返回一条数据的数组 77 否则返回错误信息 78 */ 79 public static function fetchOne($sql){ 80 //$query=self::query($sql); 81 //return self::$db->fetchOne($sql); 82 83 $key=md5($sql); //获取要执行的sql语句的md5加密后的$key 84 $is_exit=self::m_is_exit($key); 85 if($is_exit==0){ //当前不存在$key的缓存 86 $query=self::query($sql); 87 return self::$db->fetchOne($query); 88 } 89 else{ 90 //当前缓存中存在,则从缓存中获取数据 91 return self::$mem->mGet($key); 92 } 93 } 94 95 /* 96 插入函数: 97 成功则返回插入行数的主键id 98 否则返回错误信息 99 */ 100 public static function insert($table,$arr){ 101 return self::$db->insert($table,$arr); 102 } 103 104 /* 105 更新函数: 106 成功则返回受影响的行数的主键id 107 则否返回错误信息 108 */ 109 public static function update($table,$arr,$where){ 110 return self::$db->update($table,$arr,$where); 111 } 112 113 /* 114 删除函数: 115 成功则返回受影响的行数 116 否则返回错误信息 117 */ 118 public static function del($table,$where){ 119 return self::$db->del($table,$where); 120 } 121 122 public static function findResult($sql, $row = 0, $filed = 0){ 123 $query = self::$db->query($sql); 124 return self::$db->findResult($query, $row, $filed); 125 } 126 }
这就是我们的DB引擎操作类。
在封装完DB引擎操作类之后,我们还应该封装一个视图引擎操作类,用于将数据注入视图模板和显示视图模板。这里我采用的是Smarty引擎,所以我就有我自己的配置方法、数据写入方法和模板显示方法。
1 <?php 2 /* 3 视图引擎工厂类 4 */ 5 class VIEW{ 6 public static $view; //定义一个静态的view变量,用于存储将视图操作类实例化后的对象 7 8 /* 9 视图操作类初始化和配置 10 */ 11 public static function init($viewType,$config){ 12 self::$view=new $viewType; //实例化视图操作类 13 14 //进行视图操作类配置 15 foreach($config as $key=>$val){ 16 self::$view->$key=$val; 17 } 18 } 19 20 /* 21 assign()方法的重写 22 */ 23 public static function assign($name,$data){ 24 self::$view->assign($name,$data); //向模板文件中写入动态信息 25 } 26 27 /* 28 显示模板文件的方法 29 */ 30 public static function display($url){ 31 self::$view->display($url); //显示编写好的模板文件 32 } 33 }
我将我的配置都写在了配置文件中,若是嫌麻烦,可以直接写在这个文件中,直接进行配置。
到这里,准备工作算是完成了,接下来我觉得才是最有意思的地方。
看一下微型框架的目录结构: