PHP学习笔记,本身动手写个MVC的框架

最新在你们本身的博客的过程当中,发现各类开源的博客系统都或多或少的用起来别扭.因而想动手本身写个博客系统.既然写,就想好好写.那就先写个MVC框架.一点一点来.写的过程当中有不少想法.还但愿你们可以多多指正.我在这里先把它们记录下来.下面是我对这个系统的一些想法.php

1,我要实现一个模块话的博客系统,可以进行二次开发.mysql

2,我要实现apache和nginx的rewrite功能.nginx

3,我要实现对多数据库的支持.包括mongodb和mysql 还有mysqli.等.sql

4,我要把smarty用起来.mongodb

好,下面动手开始写.首先一点我得设计一下这个系统.大概的目录结构是下面这个样子的(我参考了PHPCMS).数据库

/apache

./log--这个是日志目录.我想把日志记录在这个里面数组

./system ---这个是系统目录mvc

  ./lib--这个是系统库.关键的东西都放在这里面框架

    ./classes -- 这个是系统的相关类

    ./configs--这个是系统的配置文件目录

./model--这个是各个数据模型的目录

./modules--这个是各个模块的目录

  ./base.php--全部的请求都路由到这个文件上面来了,再有这个文件来分发.

  ./index --我把index也当成一个模块来写

./templates--这个是模板目录

  ./default--这个是默认的模板目录

./cache--这个是cache目录.

index.php-----------这个是单入口文件,用来路由相关的请求.

MVC框架要把model和ctrl还有view分开.那么就须要url的路由.至于伪静态什么的,后面再说.要先知足最基本的需求.

MVC框架要有个单入口文件,因而第一个文件产生了.就是根目录下面的index.php,这个文件用来接收全部的请求,也就是说全部的请求都是从这个入口进来的.关于单入口的好处,请自行搜索脑补.

每个数据模型,按照个人理解,应该对应一张或者多张表.好比文章模型.能够单独对文章表.也能够对应做者表and文章表and评论表.

涉及到数据模型就要与数据库打交道了.先无论跟数据库打交道.我最早要实现的是可以路由个人URL

最简单的url     http://域名.com要路由到index模块下的index.php文件里面的index控制器而且执行这个控制器的默认方法(我设置成了init);

既然要有默认的路由参数,我就创建了一个文件.叫default_arg.config.php  存放在/system/lib/configs/default_arg.config.php里面用来返回默认的参数

里面的内容大概是介个样子滴:

<?php
	return array(
		  'default' =>
		   array(
				'm'=>'index',
				'c'=>'index',
				'a'=>'init',
				),
		  );

  当我想引用这些配置的时候 .我只须要以下的调用

$configs = include_once($file);

  就可以将这个大数组赋值到configs上面,若是没有参数,就使用默认的参数.把默认参数拼接到URL上面.个人默认首页就变成了

http://域名.com/index.php?m=index&c=index&a=init

这一切的功能是怎么实现的哦?

 既然访问的是index.php,那就从index.php开始看,其实index里面就几行,

define('ROOT_PATH',dirname(__FILE__));//定义一个系统路径
require_once(ROOT_PATH.DIRECTORY_SEPARATOR.'system'.DIRECTORY_SEPARATOR.'base.php');//引用框架的基础类
$sys = base::getInstance();//获得基础类的实例,基础类是一个单例类
$sys->init();//调用单例类的init方法

  其实DIRECTORY_SEPARATOR就是个/,咱们能够这样理解.引用了框架里面的base文件.而后调用了里面的getInstance方法.获得了一个实力,最后调用了init方法.

为何要使用单例类,能够自行百度.这里用单例类比较科学.后面我会把整个类贴上来,下面用到什么就贴什么.

再看看base类里面的getInstance干了些什么.

class base{
	public static $sys;
	private function __construct(){
		return false;
	}
	public static function getInstance(){
		if(!(self::$sys instanceof self)){
			self::$sys = new self();
		}
		return self::$sys;
	}

  由于是单例类,我把base里面的构造方法声明成了私有的.这是为了防止被new关键字从外部new这个类.为了保证全部操做都是由单一实例来完成的.这个类是不容许在外部new的.

在看看getInstance方法.先判断本身的$sys变量是否是本身的实例.若是不是就将本身的实例赋值给$sys,若是是则不作操做,最后 返回了这个类本身的一个实例.

在看看init方法作了些什么

	public static function init(){
		self::sys_class('model');
		self::sys_class('ctrl');
		$args = self::__explan_arg();
		$ctrl = self::__load_ctrl($args['m'],$args['c']);
		call_user_func(array($ctrl,$args['a']));
	}

  我在这个基础类里面写了几个方法.若是方法名称前面有两个下划线,就是私有的方法.   有个sys_class就是在指定目录加载系统了.这个目录是/system/lib/class/.  这里加载了model类和ctrl类,就是模型类的基类和控制器类的基类.这个ctrl类是全部控制器的基类.里面能够写一些公共的方法.好比说在构造方法让类中有一个base的实例神马的.让全部的控制器都集成自这个类.这个model类目前还没用到.可是之后的数据模型都应该是来自这个model类的.后面会说.

  而后我调用了__explan_arg方法.这个方法就是来解析get获得的参数的.

	private static function __explan_arg(){
		$default_arg = self::sys_config('default_arg');
		$args['m'] = isset($_GET['m'])?$_GET['m']:$default_arg['m'];
		$args['c'] = isset($_GET['c'])?$_GET['c']:$default_arg['c'];
		$args['a'] = isset($_GET['a'])?$_GET['a']:$default_arg['a'];
		return $args;
	}

  我在第一行使用了一个sys_config方法来加载默认参数.这个方法就是在系统的/system/lib/configs/目录下面找到对应的配置文件,上面已经说过了怎么把数组返回.这样当GET里面没有相应的参数的时候就会使用默认的参数.接下来咱们调用了__load_ctrl方法加载了相应的控制器.传入了m和c.这个方法实现的就是到m所指定的目录下面找到c这个文件而且实例化一个c这个类(也就是相应的控制器类.)而且返回相应控制器类的实例.而后我调用了一个call_user_func方法.由于咱们没办法在程序里像下面的样子来调用控制器的方法

$ctrl->$args['a'];//这样是没办法调用的

 因此咱们使用了call_user_func方法来调用相应控制器的方法.

好了,如今再缕缕咱们程序的流程.首先访问了index.php-->index.php定义了一个路径,去引用了base类.而且获得了一个base类的实例.还调用了base的init方法.-->base的init方法作了下面的事情-->先去引用了基类model和ctrl-->去解析了url中的参数,获得了m,c,a-->经过m,c来引用相应的控制器,-->调用相应控制器的a方法.而后就会获得相应的输出了.

 

  到此为止咱们的框架控制器部分基本算是完成了,默认的args是index,index,init.咱们在/modules/index/里面创建一个index.php文件.里面写以下的内容.

<?php
class c_index extends ctrl{
	public function __construct(){
		parent::__construct();
	}
	public function init(){
		echo "hello my mvc!";
	}
}

  再来访问咱们的根域名,那么咱们就会获得hello my mvc.这句话的输出.

 

 

----------------------------------------------------------------------------------------------------------------------------------

毕竟是本身我的的思路.若是有什么不妥的地方,欢迎你们拍砖,也但愿你们可以一块儿来参与讨论,最近看到php的相关板块不像之前那么火了.还但愿你们可以多多来参与发帖和讨论.

相关文章
相关标签/搜索