您的位置:首页 > 编程语言 > PHP开发

(1)php框架开发---路由转发

2017-07-13 20:42 393 查看
第一次写php框架,之前都是使用Tp框架,所以自己就想做一个框架练一下手。也好学习一下php原生的知识,不然原生不常用了,就像生锈的柴刀一样,变得不锋利了。废话就不多说了,现在就进入我们的第一讲,php的路由转发功能实现。

在这里,如果你是新手,这不是重点,因为我也是菜鸟,所以我写的转发也不会说太难。而且现在也不会涉及到设计模式上的东西,毕竟一下子要消化完的话,还是有点吃力。不过在这里,你要会正则表达式,不然你看我的这篇文章的话会体会到什么是绝望。所以没有学习正则的盆友,可以参考我的这篇文章(传送门)。

第一讲,我们首先要了解一下$_SERVER[]这个超级变量,因为我们是要在这个变量上找到URL地址,还有打开的脚本是XXX.php脚本。这里面我主要讲几个要用到的。

①$_SERVER['PHP_SELF']:相对于网站根目录的路径及 PHP 程序名称,与 document root 相关。

②$_SERVER['SCRIPT_NAME']:相对于网站根目录的路径及 PHP 程序文件名称 。

③$_SERVER['SCRIPT_FILENAME']:当前运行 PHP 程序的绝对路径及文件名。

④$_SERVER[''REQUEST_URI'']:访问此页面所需的 URI 。

⑤$_SERVER['DOCUMENT_ROOT']:当前运行 PHP 程序所在的文档根目录,在服务器配置文件中定义。

⑥$_SERVER['PATH_INFO']:提取文件路径之后的/.例如:index.php/m/mm/c/cc/a/aa?a=1这个链接会提取/m/mm/c/cc/a/aa

了解完这些东西之后,相信你对于如何提取URL的信息就更加熟悉了。之后我们就要根据这个信息来提取出一个route类出来。

第一个要做的是单一入口,这里规定只能是index.php才能够进入。这里我们可以利用$_SERVER['PHP_SELF']变量来进行判断是否在index.php文件中进入。这里我们就要使用到强大的正则了。

public function __construct()
{
//找到根目录路径
preg_match('#(.*)/index.php#',$_SERVER['PHP_SELF'],$path);
//这个是用来保存整个路径就是PHP_SELF的内容
$this->_root_path = $path[0];
//这个是正则上的括号里面的内容,就是除了index.php以外的路径
$this->_dir = $path[1];
}

使用上面的方式我们就可以很轻松的拿到了这里面的信息,并且保存起来。其实这里可以直接使用dirname函数来提取_dir里面的内容的,但是我不会这样做。因为我刚学正则不久,要装下逼嘛。

然后就到了关键的一步了,这里的话要判断是否在入口文件进入。

//检查路由
public function checkRoute(){
//规定入口文件一定要在index.php
preg_match('#index.php$#',$_SERVER['SCRIPT_FILENAME'],$arr);

if(@$arr[0] != 'index.php'){

echo '入口文件写错了';
return false;
}
//找到所属的model,controller,action
preg_match('#/index.php/([^?]*)#',$_SERVER['REQUEST_URI'],$arr);
$tmp = explode('/',$arr[1]);
if(count($tmp)!=3){
echo '不是合法的请求!'.'<br/>';
return false;
}
$this->_module = $tmp[0];
$this->_controller = $tmp[1];
$this->_action = $tmp[2];
return true;
}

上面的代码在判断是否在index.php为入口函数上肯定是有一定的错误的,因为只是判断当前运行的文件是否为index.php而已,所以在其它地方的index.php也是可以打开的。但是我觉得可以放松一点入口文件的位置,不用固定放置。而且我对于框架来说的话也不是太懂,现在还是探索阶段。

这里面的第二个正则其实就是利用PHAT_INFO来进行提取URL中的模块,控制器,方法。因为我是采用如下的URL方式:http://SERVERNAME/index.php/module/m/controller/c/action/a?参数=1&参数=2这种形式,所以如果是在/中提取到的数据有超过三个值的话,证明是不符合MVC框架的。所以这里面就要判断是错误的URL,不让其进行URL的跳转操作了。

然后就到了路由转发这一部分了,根据上面的路由变量的存储$this->_module,$this->_controller,$this->_action。我们可以方便的知道这里的mvc了,然后就可以根据这里的m找到网站根目录下的同名文件夹,然后像找m一样找其它的文件夹下面的文件了。

//路由跳转
public function jumpRoute(){
if($this->checkRoute()){
$arr = explode('/',$_SERVER['PATH_INFO']);
$url = '/'.$arr[1].'/'.'view/'.$arr[2].'/'.$arr[3].'.html';

$file = $_SERVER['DOCUMENT_ROOT'].$this->_dir.$url;
if(is_file($file)){
$html = file_get_contents($file);
echo ($html);
}else{
echo '没有当前的路径!';
}
}else{
echo '路由解析错误,请输入正确的路由!';
}

}

就这样子我们就完成了一个简单的路由转发功能了。

完成后就可以验证了,验证后的结果如下:



完整的route代码:

<?php

namespace core;

class route{
private $_dir;//不包含index.php
protected $_root_path;//包含index.php
protected $_module,$_controller,$_action;//模块,控制器,方法
public function __construct()
{
//找到根目录路径
preg_match('#(.*)/index.php#',$_SERVER['PHP_SELF'],$path);
$this->_root_path = $path[0];
//echo $this->_root_path.'<br/>';
$this->_dir = $path[1];
//echo $this->_dir.'<br/>';
}
//检查路由
public function checkRoute(){
//规定入口文件一定要在index.php
preg_match('#index.php$#',$_SERVER['SCRIPT_FILENAME'],$arr);

// echo $_SERVER['SCRIPT_FILENAME'].'<br/>';
// echo $_SERVER['PHP_SELF'].'<br/>';
// echo $_SERVER['REQUEST_URI'].'<br/>';

if(@$arr[0] != 'index.php'){

echo '入口文件写错了';
return false;
}
//找到所属的model,controller,action
//$url = explode('/',$_SERVER['REQUEST_URI']);
//var_dump($url);
preg_match('#/index.php/([^?]*)#',$_SERVER['REQUEST_URI'],$arr);
//var_dump($arr[1]);
$tmp = explode('/',$arr[1]);
//var_dump($tmp);
//echo '<br/>';
if(count($tmp)!=3){
echo '不是合法的请求!'.'<br/>';
return false;
}
$this->_module = $tmp[0];
$this->_controller = $tmp[1];
$this->_action = $tmp[2];
return true;
}
//路由跳转
public function jumpRoute(){
if($this->checkRoute()){
//echo $this->_root_path.'/'.$this->_module.'/'.$this->_controller
// .'/'.$this->_action.'.html'.'<br/>';
//echo $_SERVER['DOCUMENT_ROOT'].'<br/>';
//echo $_SERVER['PATH_TRANSLATED'].'<br/>';
//echo $_SERVER['PATH_INFO'].'<br/>';
$arr = explode('/',$_SERVER['PATH_INFO']);
$url = '/'.$arr[1].'/'.'view/'.$arr[2].'/'.$arr[3].'.html';
//echo $url.'<br/>';
$file = $_SERVER['DOCUMENT_ROOT'].$this->_dir.$url;
if(is_file($file)){
//$html = file_get_contents($file);
//echo ($html);
}else{
echo '没有当前的路径!';
}
//var_dump($arr);
}else{
echo '路由解析错误,请输入正确的路由!';
}

}
//module,controller,action返回接口
public function getMvc(){
return [$this->_module,$this->_controller,$this->_action];
}
}

前台页面:



后台页面:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  php 框架 自写框架