他们的工作原理大家应该也比较感兴趣,下面我说说一个mvc框架长什么样。
路由机制
在互联网我们都是通过url提供服务,因此不同的url有不同的服务。用户访问不同的页面也就获得了不同的服务。那么我们的服务是如何通过url来区分不同的服务呢。
我们的web程序就要通过url寻找到不同的文件,进行不同的业务逻辑处理。我们的路由机制就是根据url,寻找到对应的controller,和action,然后由action进行具体的业务逻辑处理。
一个简单的controller
class UserControler extends Controller{
//定义一个action方法,注意一定是public的
public function index(){
// do business code
}
}
具体的对应规则不同的框架映射不同。以下是CodeIgniter框架的URL路由,它会尽力的尝试各种的可能,来分析URL的情况。
if (PHP_sapi_name() == 'cli' or defined('STDIN')){
$this->_set_uri_string($this->_parse_cli_args());
return;
}// 首先尝试 REQUEST_URI 这个适应大部分的情况
if ($uri = $this->_detect_uri()){
$this->_set_uri_string($uri);
return;
}// 看看PATH_INFO变量是否存在?Nginx需要配置
// Note: some servers seem to have trouble with getenv() so we'll test it two ways
$path = (isset($_SERVER['PATH_INFO'])) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO');
if (trim($path,'/') != '' && $path != "/".SELF){
$this->_set_uri_string($path);
return;
}// 没有PATH_INFO,看看 QUERY_STRING?
$path = (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING');
if (trim($path,'/') != ''){
$this->_set_uri_string($path);
return;
}//尝试去从 $_GET 获取信息
if (is_array($_GET) && count($_GET) == 1 && trim(key($_GET),'/') != ''){
$this->_set_uri_string(key($_GET));
return;
}// 尽力了,放弃了路由
$this->uri_string = '';
return;
通过上面的尝试,接下来就是如何利用路由机制加载正确的controller了。
Controller加载机制
我们来看看Codeigniter框架是如何加载到controller并且调用action的。
在/system/core/Codeigniter.PHP中有如下的代码。Codeigniter在这之前会根据$_SERVER['PATH_INFO]里面的值来进行赋值(这个都是靠自己的设定的,默认的话CI他会有许多的if分支进行判断)。
include(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().'.PHP');$class = $RTR->fetch_class();
$method = $RTR->fetch_method();//大约在308行
$CI = new $class();//大约在359行
call_user_func_array(array(&$CI,$method),array_slice($URI->rsegments,2));
就这样,通过这个就调用到了我们的controller及其方法了,接下来就是编写自己的业务逻辑代码了。
视图view的显示
当我们的业务逻辑代码写完后,就需要页面的展示了。很多常见的MVC框架在页面的调用是这么写的。
public function index(){
// ... 许多的业务逻辑代码
$data = array('name'=>'abc','age'=>12,.... );
return $this->render('view/path/file.html',$data);
}
接着在视图文件view/path/file.html里写上一下代码。
姓名 : =$name ?>
年龄 :