You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
195 lines
4.3 KiB
195 lines
4.3 KiB
10 months ago
|
<?php
|
||
|
/**
|
||
|
* The Router class
|
||
|
*/
|
||
|
class LtRouter
|
||
|
{
|
||
|
public $configHandle;
|
||
|
public $routingTable;
|
||
|
public $module;
|
||
|
public $action;
|
||
|
|
||
|
public function __construct()
|
||
|
{
|
||
|
if (! $this->configHandle instanceof LtConfig)
|
||
|
{
|
||
|
if (class_exists("LtObjectUtil"))
|
||
|
{
|
||
|
$this->configHandle = LtObjectUtil::singleton("LtConfig");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
$this->configHandle = new LtConfig;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public function init()
|
||
|
{
|
||
|
$this->routingTable = $this->configHandle->get("router.routing_table");
|
||
|
if (empty($this->routingTable))
|
||
|
{
|
||
|
$this->routingTable = array('pattern' => ":module/:action/*",
|
||
|
'default' => array('module' => 'default', 'action' => 'index'),
|
||
|
'reqs' => array('module' => '[a-zA-Z0-9\.\-_]+',
|
||
|
'action' => '[a-zA-Z0-9\.\-_]+'
|
||
|
),
|
||
|
'varprefix' => ':',
|
||
|
'delimiter' => '/',
|
||
|
'postfix' => '',
|
||
|
'protocol' => 'PATH_INFO', // REWRITE STANDARD
|
||
|
);
|
||
|
}
|
||
|
|
||
|
$delimiter = $this->routingTable['delimiter'];
|
||
|
$postfix = $this->routingTable['postfix'];
|
||
|
$protocol = strtoupper($this->routingTable['protocol']);
|
||
|
$module = '';
|
||
|
$action = '';
|
||
|
$params = array();
|
||
|
// HTTP HTTPS
|
||
|
if (isset($_SERVER['SERVER_PROTOCOL']))
|
||
|
{
|
||
|
if (isset($_SERVER['PATH_INFO']) && !empty($_SERVER['PATH_INFO']))
|
||
|
{
|
||
|
// 忽略后缀
|
||
|
$url = rtrim($_SERVER['PATH_INFO'], "$postfix");
|
||
|
$url = explode($delimiter, trim($url, "/"));
|
||
|
}
|
||
|
else if (isset($_SERVER['REQUEST_URI']))
|
||
|
{
|
||
|
if ('REWRITE' == $protocol)
|
||
|
{
|
||
|
if (0 == strcmp($_SERVER['REQUEST_URI'], $_SERVER['SCRIPT_NAME']))
|
||
|
{
|
||
|
$url = array();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
$url = substr($_SERVER['REQUEST_URI'], strlen(pathinfo($_SERVER['SCRIPT_NAME'], PATHINFO_DIRNAME)));
|
||
|
$url = rtrim($url, "$postfix");
|
||
|
$url = explode($delimiter, trim($url, "/"));
|
||
|
}
|
||
|
}
|
||
|
else if ('PATH_INFO' == $protocol)
|
||
|
{
|
||
|
$url = substr($_SERVER['REQUEST_URI'], strlen($_SERVER['SCRIPT_NAME']));
|
||
|
$url = rtrim($url, "$postfix");
|
||
|
$url = explode($delimiter, trim($url, "/"));
|
||
|
}
|
||
|
else //STANDARD
|
||
|
{
|
||
|
$url = array();
|
||
|
foreach($_GET as $v)
|
||
|
{
|
||
|
$url[] = $v;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
$url = array();
|
||
|
foreach($_GET as $v)
|
||
|
{
|
||
|
$url[] = $v;
|
||
|
}
|
||
|
}
|
||
|
$params = $this->matchingRoutingTable($url);
|
||
|
$module = $params['module'];
|
||
|
$action = $params['action'];
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// CLI
|
||
|
$i = 0;
|
||
|
while (isset($_SERVER['argv'][$i]) && isset($_SERVER['argv'][$i + 1]))
|
||
|
{
|
||
|
if (("-m" == $_SERVER['argv'][$i] || "--module" == $_SERVER['argv'][$i]))
|
||
|
{
|
||
|
$module = $_SERVER['argv'][$i + 1];
|
||
|
}
|
||
|
else if (("-a" == $_SERVER['argv'][$i] || "--action" == $_SERVER['argv'][$i]))
|
||
|
{
|
||
|
$action = $_SERVER['argv'][$i + 1];
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
$key = $_SERVER['argv'][$i];
|
||
|
$params[$key] = $_SERVER['argv'][$i + 1];
|
||
|
}
|
||
|
$i = $i + 2;
|
||
|
}
|
||
|
}
|
||
|
// 如果$_GET中不存在配置的变量则添加
|
||
|
foreach($params as $k => $v)
|
||
|
{
|
||
|
!isset($_GET[$k]) && $_GET[$k] = $v;
|
||
|
}
|
||
|
$this->module = $module;
|
||
|
$this->action = $action;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* url 匹配路由表
|
||
|
*
|
||
|
* @param $ [string|array] $url
|
||
|
* @return
|
||
|
* @todo 修复导致$_GET多出属性的BUG
|
||
|
* @todo 如果是rewrite或者path_info模式,可能需要unset module和action两个$_GET变量
|
||
|
*/
|
||
|
public function matchingRoutingTable($url)
|
||
|
{
|
||
|
$ret = $this->routingTable['default']; //初始化返回值为路由默认值
|
||
|
$reqs = $this->routingTable['reqs'];
|
||
|
$delimiter = $this->routingTable['delimiter'];
|
||
|
$varprefix = $this->routingTable['varprefix'];
|
||
|
$postfix = $this->routingTable['postfix'];
|
||
|
$pattern = explode($delimiter, trim($this->routingTable['pattern'], $delimiter));
|
||
|
|
||
|
/**
|
||
|
* 预处理url
|
||
|
*/
|
||
|
if (is_string($url))
|
||
|
{
|
||
|
$url = rtrim($url, $postfix); //忽略后缀
|
||
|
$url = explode($delimiter, trim($url, $delimiter));
|
||
|
}
|
||
|
|
||
|
foreach($pattern as $k => $v)
|
||
|
{
|
||
|
if ($v[0] == $varprefix)
|
||
|
{
|
||
|
// 变量
|
||
|
$varname = substr($v, 1);
|
||
|
// 匹配变量
|
||
|
if (isset($url[$k]))
|
||
|
{
|
||
|
if (isset($reqs[$varname]))
|
||
|
{
|
||
|
$regex = "/^{$reqs[$varname]}\$/i";
|
||
|
if (preg_match($regex, $url[$k]))
|
||
|
{
|
||
|
$ret[$varname] = $url[$k];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else if ($v[0] == '*')
|
||
|
{
|
||
|
// 通配符
|
||
|
$pos = $k;
|
||
|
while (isset($url[$pos]) && isset($url[$pos + 1]))
|
||
|
{
|
||
|
$ret[$url[$pos ++]] = urldecode($url[$pos]);
|
||
|
$pos++;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// 静态
|
||
|
}
|
||
|
}
|
||
|
return $ret;
|
||
|
}
|
||
|
}
|