设为首页 收藏本站
查看: 718|回复: 0

[经验分享] 简易PHP路由,支持正反向url解析支持

[复制链接]

尚未签到

发表于 2017-4-10 07:42:10 | 显示全部楼层 |阅读模式
  几年前实现了一个简单的正向路由,那时候不会写反向路由解析,最近通读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的操作,如果诸位有需要,此处就算我 抛砖引玉了....
  代码很少,也就不一一解释了

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-362625-1-1.html 上篇帖子: PHP安全编程:记住登录状态的安全做法 下篇帖子: PHP检测并清除文件开头的BOM
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表