从本节起开始正式讲述mvc的开发,理论和代码一起上。
下面图片是目录结构
了解zend framework 的朋友肯定非常熟悉这样的目录结构
其中application 文件夹 是应用层的核心代码
Library文件夹 是mvc框架底层代码(咱们课程重点就是讲述这个文件夹里的文件)
www是网站的根目录,明显看到 网站跟目录和 application以及library 没有包含在www目录里,这样也可以起到一定的安全作用,www目录中放置模板,图片等一些代码
本节主要讲述和网站入口相关的三个文件 图中中已经用红色表示出
首先看看.htaccess文件代码
SetEnv APPLICATION_ENV development
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
这个文件相当于apache服务器的配置文件一部分,每次当客户访问网站的时候,apache服务器都会先查看.htaccess文件的内容,然后再执行相关的请求,对.htaccess文件不了解的朋友直接google一下,资料很多.
上面几行代码的作用是: 如果访问的目录或文件不存在,全部执行index.php文件,举个例子大家就明白了, 比如用户访问 http://tianliangle.com/a/b.html 如果网站根目录中确实存在这个文件,那么久执行 a目录下的b.html文件,如果没有这个相关文件 则执行index.php文件。有人可能会问,为什么不把所有的请求都指向index.php文件,这样不更好吗?这样做的不妥之处在于,但用户请求js文件css文件图片文件时,没必要指向index.php,还有很多功能,也没必要执行index.php 文件
假如用户请求的地址为 http://tianliangle.com/a/b/c/1
Mvc 框架需要解决的基础问题是,通过地址栏 确定唯一的moudle, conttoller, action
由上面可知道,服务器指向了index.php文件
Index.php 代码
<?php
header("content-Type: text/html; charset=utf-8");
define("COMMON_AUTH",TRUE);
!defined("COMMON_AUTH") && dir("NO_AUTH");
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
//error_reporting(0);
error_reporting(0);
// Define base path obtainable throughout the whole application
defined('BASE_PATH')
|| define('BASE_PATH', realpath(dirname(__FILE__)).'/../');
// Define path to application directory
defined('APPLICATION_PATH')
|| define('APPLICATION_PATH', BASE_PATH . '/application');
// Define application environment
defined('APPLICATION_ENV')
|| define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production'));
defined('WEB_ROOT')
|| define('WEB_ROOT', BASE_PATH . 'www');
/**
* 设置模板类型
*/
$_web_tpl ='view';
// Define application environment
// Set include path to Zend (and other) libraries
set_include_path( PATH_SEPARATOR . BASE_PATH . '/library' .
PATH_SEPARATOR . APPLICATION_PATH . '/models' .
PATH_SEPARATOR . APPLICATION_PATH . '/modules' .
PATH_SEPARATOR . WEB_ROOT . '/config' .
PATH_SEPARATOR . APPLICATION_PATH . '/function' .
PATH_SEPARATOR . get_include_path() .
PATH_SEPARATOR . '.'
);
session_start();
define("WEB_AUTH",TRUE);
include_once APPLICATION_PATH.'/route.php';
?>
代码的作用是配置一些和项目相关的变量,设置一下include 目录
最后 include_once APPLICATION_PATH.'/route.php'; 把请求指向 route.php文件中
让我们看看route.php文件时如果解析http://tianliangle.com/a/b/c/1 并确定moudle, conttoller, action
Route.php
<?php
/**
* 实现路由 认证 权限认证,以及 初始化
*/
defined("WEB_AUTH") || die("NO_AUTH");
/**
* 包含基本配置文件
*/
include_once 'config.ini.php';
/**
* 包含路由规则配置文件
*/
include_once 'route.ini.php';
/**
* 包含所有模块 控制器列表
*/
include_once 'mvc.ini.php';
/**
* 包含所有权限配置
*/
include_once 'role.ini.php';
/**
* 包含路由类 路由核心类
*/
include_once 'route/route.class.php';
/**
* 包含公用函数库
*/
include_once 'global.func.php';
/**
* 初始化路由 实现 基本派遣
*/
$route = new Route();
//$route->viewMvc();
//print_r($_GET);
/**
* 初始化程序所需的配置
*/
include_once 'common.ini.php';
/**
* 执行程序
*/
$route->run();
?>
文件包含了一些项目配置文件,主要是些变量声明
这里重点说说include_once 'route.ini.php'; 这个文件作用是给指定的地址形式配置固定的moudle, conttoller, action, 以便在以后程序中查看,本文中会讲到
举个列子
include_once 'route.ini.php
$routeArr = array(
"/reg" => array(
"mac" =>array("module"=>"default","conttoller"=>"index","action"=>"reg"),
));
这个配置的作用是 当用户请求http://tianliangle.com/reg 的时候 就执行"module"=>"default","conttoller"=>"index","action"=>"reg" 对应的模块 而不用请求http://tianliangle.com/default/default/reg 起到缩短地址的作用
然后
include_once 'route/route.class.php';
$route = new Route();
*/
$route->run();
我们可以知道 整个解析http://tianliangle.com/a/b/c/1 并派发 的实现是在 new Route() 时完成的,也就是在 Route类的析构函数中完成
route/route.class.php // 只粘贴核心的代码
<?php
/**
* 本文件实现路由解析功能 和 路由检测功能 以及 权限认证功能
*
*/
/**
* 本文件只能被index。php包含
*/
defined("WEB_AUTH") || die("NO_AUTH");
/**
* 路由类
*
*/
class Route{
/**
* 模块
*/
private $_moudle;
/**
* contro控制器
*/
private $_conttoller;
/**
* action
*/
private $_action;
/**
* 地址uri
*/
private $_uri;
/**
* 所有mvc资源
*/
private $moudle_arr;
/**
* 所有路由配置资源
*/
private $route_arr;
/**
* 访客角色
*/
private $_role = "guest";
/**
* the page to direct to if there is not current user
*
* @var unknown_type
*/
private $_default = array('module' => 'default',
'conttoller' => 'index',
'action' => 'index');
/**
* the page to direct to if there is not current user
*
* @var unknown_type
*/
private $_adminDefault = array('module' => 'admin',
'conttoller' => 'index',
'action' => 'login');
/**
* 初始化,传入参量
* @return bool
*/
public function __construct($uri = NULL)
{
global $moduleArr,$routeArr;
$this->moudle_arr = $moduleArr;
$this->route_arr = $routeArr;
$uri == NULL && $uri = $_SERVER['REDIRECT_URL'];
$this->_uri = $uri;
/*路由选取*/
$this->init();
}
/**
* 实现所有路由相关的认证
*
*/
private function init()
{
/**
* 接续url 得到相关参数
*/
$this->parseUri(); //这个函数实现了地址栏的解析
/**
* 根据路由信息得到 三层控制器
*/
$this->parseRoute();
/**
* 检查三层控制器 是否在本项目中存在
*/
$this->checkMvc();
/**
* 解析后台地址uri
*/
$this->getRealUri();
/**
* 得到当前访问者的角色
*/
$this->getRole();
/**
* 检测权限
*/
$this->checkAuth();
//$this->viewMvc();
}
/**
* 执行相应的 MCA
*
*/
public function run()
{
//$this->checAuth();
$this->runMvc();
/**
* 下面供调试使用
*/
}
…….
详细讲述一下init() 中得函数功能
$this->parseUri();
private function parseUri($uri = NULL)
{
$uri == NULL && $uri = $this->_uri;
$this->uriArr = explode('/',$uri);
$this->uriArr && $this->uriArr = array_filter($this->uriArr);
}
这个函数把地址简单根据/符号解析 并放在一个数组里面
$this->parseRoute();
这个函数的作用是:给某些请求固定设定好的moudle, conttoller, action,实现上面提到的当用户请求http://tianliangle.com/reg 的时候 就执行"module"=>"default","conttoller"=>"index","action"=>"reg" 对应的模块 而不用请求http://tianliangle.com/default/default/reg 起到缩短地址的作用
$this->checkMvc();
这个函数的主要作用是,根据系统中配置文件及$this->parseRoute();
最终确定唯一的moudle, conttoller, action,