`

简易PHP路由,支持正反向url解析支持

阅读更多

几年前实现了一个简单的正向路由,那时候不会写反向路由解析,最近通读qee v3的代码,因为其中已经扣除了路由解析这个功能,故自己结合之前的经验,发现写个简单的正反向路由解析还是蛮简单的,见代码:

 

<?php
/*
 * 静态页配置文件
 * 
 * key	为 pattern
 * 值	为 配置参数
 * 
 * 越上面的优先级越高
 */
return array(
		
	array(		
		'pattern' => 'core-{id}-{name}.html',

		'action'  => 'core/show',
		'config'	=> array(
			'id'	=> '[0-9]+',
			'name'	=> '[a-z][a-z_0-9]+'
		),
		'default'	=> array(
			'id'	=> 2,
			'name'	=> 'sfken'
		),		
	),

	array(
		'pattern' => 'admin.html',
	
		'action'  => 'admin/index',
	),

);

上面是配置文件

 

<?php
class Tool_PageStatic {
	
	private $_obj_id;	
	private $_cache;
	private $_accessor;	
	private $_config = array();
	
	private $_result = array();
		
	function __construct(array $config)
	{
		if ( empty($config['obj_id']) )
        {
        	# 对象标识 用于缓存配置文件等用,标识系统中的 ps 对象的实例标识
        	throw BaseError::invalid_parameters_error('key "obj_id" not set');
        }
        $this->_obj_id = $config['obj_id'];		
        
		$this->_accessor = val( $config , 'accessor' , 'page' );
		$this->_cache = val( $config , 'cache' , NULL );
		
		$cfopt = val( $config , 'config' , null );
		if ( !empty($cfopt) )
		{
			if ( is_array($cfopt) )
			{
				$this->loadConfig($cfopt);
			}
			if ( is_file($cfopt) )
			{
				# 如果是文件是否需要从缓存中进行读取,还是每次都要读取此处的配置文件				
			
				$cfopt = include($cfopt);
				$this->loadConfig( (array) $cfopt);
			}
		}
		
		$cfopt = null;
		
		$this->default = array(
			'action' => Config::get('app.default_action','index'),
			'nocache' => TRUE,
			'params' => array(),
		);
		
	}
	
	private function loadConfig( array $config )
	{
		foreach ( $config as $opts )
		{
			# 对于 未设置 action & pattern 的配置项 直接忽略
			if ( empty($opts['action']) || empty($opts['pattern']) ) continue;
			
			$opts['src_pattern'] = $opts['pattern'];
			
			if ( !empty($opts['config']) )
			{
				foreach($opts['config'] AS $conf_key => $conf_val)
			    {
				    $opts['pattern'] = str_replace('{'.$conf_key.'}', '('.$conf_val.')', $opts['pattern']);
			    }
			}
			else
			{
				$opts['config'] = array();
			}
			if ( empty($opts['default']) ) $opts['default'] = array();
						
			$this->_config[strtolower($opts['action'])] = $opts;
		}
		
		# 解析完成后是否可以存入缓存		
	}
	
	function getAccessor()
	{
		return $this->_accessor;
	}
	
	/**
	 * 解析 string 返回对应的action以及相应的参数
	 *
	 * @param string $string
	 * 
	 * @return array
	 */
	function parsing($string)
	{	
//		dump($this->_config);
			
		if ( empty($string) || empty($this->_config) ) return $this->default;
		
		if ( empty($this->_result[$string]) )
		{
			$d = $this->default;
			
			foreach($this->_config AS $opts)
			{
				if (preg_match('#^'.$opts['pattern'].'/?$#i', $string, $match_result))
				{
//					dump($match_result);
					
					# offset 为0 是 原字符串
			    	$offset = 1;
			    	foreach($opts['config'] AS $conf_key => $conf_val)
			    	{
			    		if(isset($match_result[$offset]))
			    		{
				    		$d['params'][$conf_key] = $match_result[$offset++];
			    		}
			    	}
					
					$d['nocache'] = val($opts,'nocache',$d['nocache']);
					$d['action'] = $opts['action'];
					break;
				}
			}
			
			$this->_result[$string] = $d;
		}
		
		return $this->_result[$string];
	}
	
	/**
	 * 生成静态的 url 地址
	 *
	 * @param string $action_name
	 * @param array $params
	 */
	function psurl( $action_name , array $params = null )
	{
		$opts = val( $this->_config , strtolower($action_name) , null );	
		if ( !empty($opts) )
		{
			$params = (array) $params;
			
			# 使用源 $opts['src_pattern']
			$url = $opts['src_pattern'];
			dump($url);
        	foreach($opts['default'] AS $d_key => $d_val)
        	{
        		if ( !empty($params[$d_key]) )
        		{
        			$d_val = $params[$d_key];
        			unset($params[$d_key]);
        		}        		
//        		$url = str_replace(':'.$d_key, $d_val, $url);
        		$url = str_replace('{'.$d_key.'}', $d_val, $url);
        	}
			return $url . '?' . http_build_query($params);
		}
		
		# 如果没有找到就生成原始的url
		return url($action_name , $params);
	}
	
}

 上面是真正的实现代码

 

下面是调用代码

<?php
/**
 * 站点静态化操作
 * 
 * /static/page/article-php-json_encode.html
 * 
 * 
 */
class Action_Static extends BaseAction 
{
	
	protected function _validate_input()
    {	
    	$engine = $this->app->tool('pagestatic');    	
    	$accessor = $engine->getAccessor();
    	
    	$this->pid = $_GET[$accessor];// page 标识
    	
    	if ( !empty($this->pid) && strlen($this->pid) < 230 )
    	{
    		// 为什么不在此处直接读缓存? 目的是实现未在配置文件中定义的过期缓存全部设为失效
    		
    		$this->pparams = (array) $engine->parsing($this->pid);// page 参数
    		
    		if ( !empty($this->pparams) )
    		{
    			return true;
    		}
    		
    	}
    	
        return false;
    }
    
    /**
     * 请求前对数据进行验证失败时调用此方法
     */
    protected function _on_validate_input_failed()
    {
    	// 记录错误日志(将 pid 记录到错误日志中)
    	
    	
    	// 跳转到首页
    	redirect( url(Config::get('app.default_action','index')) );
    }
    
    
	function execute()
	{
		$cached = val($this->pparams,'nocache',FALSE);
		
		dump($this->pparams,$this->pid);
		
		dump( $this->app->tool('pagestatic')->psurl('core/show',array(
			'id' => '449211678',
			'name' => 'kenxu',
			'age' => '29',			
//			'blog' => 'http://vb2005xu.iteye.com',			
		)) );
	}
}

 

输出结果如下:

http://sfken.xu/static/page/admin.html 写道
admin.html :
Array
(
[action] => admin/index
[nocache] => 1
[params] => Array
(
)

)

core-{id}-{name}.html

core-449211678-kenxu.html?age=29

 

http://sfken.xu/static/page/core-12306-tianchao.html 写道
core-12306-tianchao.html :
Array
(
[action] => core/show
[nocache] => 1
[params] => Array
(
[id] => 12306
[name] => tianchao
)

)

core-{id}-{name}.html

core-449211678-kenxu.html?age=29

 

在我当前的设计中 此路由功能只能算是一个工具类,用于实现 伪静态/或者页缓存用的,功能上只支持指定action的操作,如果诸位有需要,此处就算我 抛砖引玉了....

 

代码很少,也就不一一解释了

分享到:
评论
5 楼 edikud 2014-06-19  
求一份此框架学习下,半成品也可,本人新手,谢谢,edikud@gmail.com
4 楼 vb2005xu 2013-08-06  
nginx url重写 单一入口 配置设置例子如下:

############===========xp.me=============###########   
server   
{   
	  listen       80;   
	  server_name  xp.me;   
	  index index.html index.php;   
	  root "d:/httpenv/web/xp.me";   

	  location / {   
		   if (!-e $request_filename){   
				rewrite ^(.*)$ /index.php?s=/$1 last; #rewrite模式   
				rewrite ^(.*)$ /index.php/$1 last; #pathinfo模式 任选其一   
			}   
	  }   


	  location ~ \.php {   

		   fastcgi_pass    127.0.0.1:9000;   
		   fastcgi_split_path_info ^(.+\.php)(.*)$;   
		   fastcgi_param PATH_INFO $fastcgi_path_info;   
		   fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;   
		   fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;   
		   include         fastcgi_params;   
		   fastcgi_connect_timeout 300;   
		   fastcgi_send_timeout 300;   
		   fastcgi_read_timeout 300;   
	  }   


}  
3 楼 vb2005xu 2013-06-30  
http://www.oschina.net/translate/list?type=2&sort=&p=1 开源美文
2 楼 vb2005xu 2013-06-30  
http://emberjs.com/guides/concepts/naming-conventions/ 推荐
1 楼 vb2005xu 2013-06-21  
正向解析

引用

core-449211678-kenxu.html :
Array
(
    [action] => core/show
    [nocache] => 1
    [params] => Array
        (
            [id] => 449211678
            [name] => kenxu
        )

)

core-{id}-{name}.html

core-449211678-kenxu.html?age=29

相关推荐

    基于PHP的route.class.最简单轻量的url路由,支持正反向url解析.zip

    它支持正反向URL解析,意味着你可以方便地从URL生成控制器路径,反之亦然。 路由类的基本工作原理是通过定义规则来解析URL中的各个部分,然后根据这些规则调用相应的处理程序。例如,一个简单的路由规则可能如下所...

    基于PHP的route.class.最简单轻量的url路由,支持正反向url解析源码.zip

    总之,"route.class.php"提供了一种轻量级的PHP URL路由解决方案,它的正反向解析功能使开发者能更灵活地处理和构建URL,提高项目的可维护性和用户体验。通过学习和实践,我们可以更好地掌握PHP中的路由机制。

    PHP实例开发源码—route.class.最简单轻量的url路由,支持正反向url解析.zip

    4. **参数处理**:路由类可能还支持传递额外的参数,这些参数可以在URL中以查询字符串形式存在,或者被嵌入到动态部分(如`:id`)。路由类需要正确处理这些参数,确保它们能被正确地传递给目标处理程序。 在“使用...

    PHP实现一个简单url路由功能.doc

    PHP 实现简单 URL 路由功能 PHP 实现简单 URL 路由功能是指使用 PHP 语言来实现一个简单的 URL 路由功能,以便更好地管理和处理 URL。下面是该功能的详细解释和实现过程。 一、什么是 URL 路由? ----------------...

    Spring三大URL路径解析器(附工程源代码)

    在Spring框架中,URL路径解析是构建Web应用的关键部分,它允许我们定义优雅的路由规则并将请求映射到相应的处理方法。本篇文章将深入探讨Spring中的三种主要URL路径解析器,包括`SimpleUrlHandlerMapping`、`...

    nginx+php,让nginx支持PHP的PATHINFO路由模式_亲测成功.zip

    nginx+php,让nginx支持PHP的PATHINFO路由模式_亲测成功.zip apache+php支持PATHINFO路由模式非常容易,但是nginx对pathinfo可不支持,需要你自己配置正则路径.看看我怎么配的

    PHP实现一个简单url路由功能实例

    当用户访问一个URL时,路由分发器会解析这个URL,并根据URL路径中的模块名、控制器和方法名来决定调用哪个PHP文件和哪个函数(方法)。例如,如果访问的URL是***,分发器会解析出模块名Hello、控制器router以及参数a...

    TP5 URL和路由

    标题 "TP5 URL和路由" 指的是ThinkPHP5框架中的URL管理和路由规则。ThinkPHP5是一款基于PHP7.1+的轻量级、快速、稳定的PHP开发框架,广泛应用于各类Web应用开发。在这一主题中,我们将深入探讨如何在TP5中处理URL和...

    由路由生成URL规则

    而由路由生成URL的能力则是这一机制的重要组成部分,因为它不仅帮助开发者创建可读性强且结构清晰的URL,还支持SEO优化等需求。本文将详细阐述几种不同的路由配置及其对URL生成的影响,并给出具体的示例代码。 ####...

    IP路由协议疑难解析

    "IP路由协议疑难解析"这个主题深入探讨了在实际网络环境中遇到的各种问题及其解决方案,这对于网络管理员和IT专业人士来说是非常有价值的学习资源。以下是关于IP路由协议的一些关键知识点: 1. IP路由基础:IP...

    在vue中利用全局路由钩子给url统一添加公共参数的例子

    有的时候我们可能有这样的需求,比如现在url为m.taoyuewenhua.com/#/ 我们需要在用户每次跳转路由的时候监控有没有abc这个参数. 如果有,后端要求我们在以后跳转任何url的时候,都要在url携带上这个参数.就变成m....

    URL.rar_url_url解析

    **URL解析**是将一个完整的URL分解成这些组成部分的过程,这在很多场景下都是必要的,比如路由、数据请求和页面跳转。在JavaScript中,可以使用`URL`对象进行解析: ```javascript let url = new URL('...

    routd,一个小型的简单的java url路由库.zip

    当用户访问特定URL时,路由系统会解析URL,查找匹配的路由规则,并执行相应的处理逻辑。 routd库的核心功能包括: 1. **路由注册**:开发者可以使用routd提供的API,通过定义URL模板和处理函数,注册新的路由规则...

    PHP解析url并得到url参数方法总结

    本文将详细介绍PHP中解析URL并获取URL参数的两种方法,包括如何解析获取URL参数以及如何将数组拼接成URL参数形式。 首先,当拿到一个完整的URL后,如何解析并获取其中的参数是一项基础而核心的技能。在PHP中,我们...

    CCNA路由配置命令及解析

    【CCNA路由配置命令及解析】是网络管理员和学习者必备的参考资料,主要涉及Cisco路由器的配置、网络连接以及路由协议的设定。本教程旨在帮助读者掌握基础的网络配置技能,提升网络管理能力。 第一章:路由器配置...

    PHP Thinkphp5全套基础视频教程 适合新手党入门(第四课 URL和路由 - URL)

    1. **理解Thinkphp5的默认路由规则**:在没有特殊配置的情况下,如何根据URL自动解析到对应的控制器和方法。 2. **配置路由规则**:学习如何在`config/route.php`文件中定义自己的路由,包括简单的路径映射、正则...

    路由实战手册 实验一 默认路由全解析 配置

    和我我博客中的笔记配套的路由配置 路由实战手册 实验一 默认路由全解析

Global site tag (gtag.js) - Google Analytics